http://blog.acmj1991.com/?p=776
思路:求逆序数
思路:开始理解错了,以为是用最少的交换次数使数列变成递增数列。后来才知道理解错了,但是可以吧这种想法的代码贴出来,其实就是总数减去环的数量
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxN 1010
int cnt,n,key[maxN],b_key[maxN];
void low(int l,int r)
{
if(l==r)return ;
int mid=(l+r)/2;
low(l,mid),low(mid+1,r);
int st=l,en=mid+1,q=l;
while(q<=r&&st<=mid&&en<=r)
{
if(key[st]<=key[en])
b_key[q++]=key[st++];
else{
cnt+=mid-st+1;
b_key[q++]=key[en++];
}
}
if(st<=mid)
while(q<=r)b_key[q++]=key[st++];
if(en<=r)
while(q<=r)b_key[q++]=key[en++];
for(int i=l;i<=r;i++)
key[i]=b_key[i];
}
int main()
{
int t,k=1;
scanf("%d",&t);
while(t--)
{
cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&key[i]);
low(1,n);
printf("Scenario #%d:\n%d\n\n",k++,cnt);
}
}
求最少移动步数的代码
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxN 1010
int key[maxN],f[maxN],vist[maxN];
int low(int l,int r,int x)
{
if(l==r)return l;
int mid=(l+r)/2;
if(x<=key[mid])
return low(l,mid,x);
else
return low(mid+1,r,x);
}
int main()
{
freopen("1.txt","r",stdin);
int n,t;
scanf("%d",&t);
while(t--)
{
memset(vist,0,sizeof(vist));
memset(key,0,sizeof(key));
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&f[i]);
key[i]=f[i];
}
sort(key,key+n);
int sum=0;
for(int i=0;i<n;i++)
if(!vist[i]&&f[i]!=key[i]){
int m=i;
sum++;
while(!vist[m]){
vist[m]=1;
m=low(0,n-1,f[m]);
}
}
printf("%d\n",n-sum);
}
}