2.1.3
Sorting 3 valued sequnce
由于只需要求排序的次数,所以不需要完全模拟排序的过程。
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max 1000
typedef struct node
{
int a;
int b;
}node;
int cmp(const void* x,const void* y)
{
return *(int*)x - *(int*)y;
}
int main()
{
freopen("sort3.in","r",stdin);
freopen("sort3.out","w",stdout);
int n,i,j,count=0,count2=0,cur;
int sequence[max],sorted[max];
int vis[max];
node circle[max];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&sequence[i]);
sorted[i]=sequence[i];
}
qsort(sorted,n,sizeof(int),cmp);
for(i=0,cur=0;i<n;i++)
if(sorted[i]!=sequence[i])
{
circle[cur].a=sequence[i];
circle[cur].b=sorted[i];
cur++;
}
memset(vis,0,sizeof(vis));
for(i=0;i<cur;i++)
{
for(j=i+1;j<cur;j++)
if((circle[i].a == circle[j].b && circle[i].b== circle[j].a) && (vis[i]==0 && vis[j]==0))
{
count2++;
vis[i]=vis[j]=1;
break;
}
}
// if(count%2!=0)count++;
printf("%d\n",(cur-2*count2)*2/3+count2);
return 0;
}
要得到计算方法,需要仔细分析。先将原序列sequence[]排序成新的数列sorted[],再与原数列相同的位置的数配对成c(i,j)。若i!=j就把它叫做“错对”。所谓最少次数,就是要我们每次操作都能让“错对数”减少得最多。每次减少只有2种情况,-2,当且仅当2对数形为c1(i,j) c2(j,i)的时候,其它情况只能-1。
所以只要扫一遍所有位置的数,统计c(i,j)&c(j,i) 这样的错对数count1和总错对数count2。
他们的关系:
( count2 - 2*count1 )*2/3 + count2;
实际意义为:
若操作每次使他减少1,则需要count2次,但有2*count1 对数不需要进行这样的操作.最后再加上-2操作的次数。
注意到,即使是开始时不能进行-2的操作,但最后一步必定会出现-2操作(因为这时只有2对数了)所以要在最后* 2/3;
这个结论可以拓展到n的情形, *(n-1)/n.
本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。