題目:
Hint: customize quicksort to the problem. Side note: only a very complicated deterministic O(N log N) algorithm is known for this problem.
思路:
A1,完全匹配的一對
A2,比螺母小的螺絲
A3,比螺母大的螺絲
將1中的螺絲取出,用它對螺母分區,可以得到
B1. 比螺絲小的螺母
B2. 比螺絲大的螺母
代碼:
/*假設螺釘和螺帽大小沒有一樣的。
每次取nuts數組中最後一個元素到bolts數組中去找和它配對的元素,這樣可以避免nuts數組中後部元素前移。*/
#include<iostream>
using namespace std;
int partition(int *nuts,int *bolts,int lo,int hi)
{//爲了保證操作nuts和bolts數組的一致性,將每次配對成功的元素放在hi的位置。
int nuts_t = nuts[hi];
int i=lo;
int j=hi;
int bolt_match=0;
while(true)
{//在bolts中找到配的nuts並將bolts分區
while(bolts[i] <= nuts_t)
{
if(nuts_t == bolts[i])
{//先判斷匹配的情況——找到完全相同的一對
bolt_match = bolts[i];
cout<<nuts_t<<"&"<<bolts[i]<<endl;
for(int k = i + 1;k <= hi;k++)
{//把當前匹配的元素位置通過後面的元素前移一格的方式填充
bolts[k -1] = bolts[k];
}
j--;//j一定指向後面要移動的某個元素,所以需要跟着遞減1
hi--;//數組長度減1
// for(int k=lo;k<=hi;k++)
// cout<<bolts[k]<<" ";
// cout<<endl;
// i++;這裏不需要指針後移
if(i > hi)//別越界
break;
}
else
{
i++;
if(i > hi)//別越界
break;
}
}//從左往右找到第一個大的螺釘
while(bolts[j] >= nuts_t)
{
if(nuts_t == bolts[j])
{//先判斷匹配的情況
bolt_match = bolts[j];
cout<<nuts_t<<"&"<<bolts[j]<<endl;
for(int k = j + 1;k <= hi;k++)
{//把當前匹配的元素位置通過後面的元素前移一格的方式填充
bolts[k -1] = bolts[k];
}
hi--;
j--;//j指針前移
// for(int k=lo;k<=hi;k++)
// cout<<bolts[k]<<" ";
// cout<<endl;
if(j < lo)//別越界
break;
}
else
{
j--;
if(j < lo)//別越界
break;
}
}//從右往左找到第一個小的螺釘
if(i >= j)//數組掃描過一遍
{
if(i == j)
cout<<"error"<<endl;
break;
}
int tmp = bolts[i];//交換
bolts[i] = bolts[j];
bolts[j] = tmp;
}
// for(int k=lo;k<=hi;k++)
// cout<<bolts[k]<<" ";
// cout<<endl;
i = lo;
j = hi;
while(true)
{//用上面bolts數組中找到的配對的螺釘,將nuts分區
while(nuts[i] < bolt_match)
{
i++;
if(i > hi)//別越界
break;
}
while(nuts[j] > bolt_match)
{
j--;
if(j < lo)//別越界
break;
}
if(i > j)
break;
int tmp = nuts[i];//交換
nuts[i] = nuts[j];
nuts[j] = tmp;
}
// for(int k=lo;k<=hi;k++)
// cout<<nuts[k]<<" ";
// cout<<endl;
return i;//第一個比較大的元素
}
void sort(int *nuts,int *bolts,int lo,int hi)
{
if(lo == hi)
{
cout<<nuts[hi]<<"&"<<bolts[hi]<<endl;
return;
}
else if(lo > hi)
{
return;
}
int j = partition(nuts,bolts,lo,hi);
hi--;//經過一次劃分後會成功配對一次,相應的hi要減一
// cout<<"j->"<<j<<endl;
// cout<<"lo->"<<lo<<endl;
// cout<<"hi->"<<hi<<endl;
sort(nuts,bolts,lo,j-1);
sort(nuts,bolts,j,hi);
}
int main()
{
int nuts[10] = {1,3,2,4,6,5,7,9,8,0};
int bolts[10] = {7,4,1,8,5,2,9,6,3,0};
sort(nuts,bolts,0,9);
}