zoj 1440 zju

http://www.cppblog.com/menjitianya/archive/2011/04/06/143506.html

关键是如何求最少的交换次数,用到了简单哈希

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lld;
#define lowbit(x) (x&-x)
const int maxn = 100010;
int c[maxn],hash[maxn],val[maxn],a[maxn];
void update(int x,int d){
for(;x>0;x-=lowbit(x))
c[x]+=d;
}
int sum(int x){
lld ans=0;
for(;x<=maxn;x+=lowbit(x)) ans+=c[x];
return ans;
}
int main(){
int n,i,j;
while(scanf("%d",&n)!=EOF){
lld ans=0;
memset(c,0,sizeof(c));
for(i=1;i<=n;i++){
scanf("%d",&val[i]);
a[i]=val[i];
}
sort(a+1,a+1+n);
for(i=1;i<=n;i++) val[i]=upper_bound(a+1,a+n+1,val[i])-(a+1);
for(i=1;i<=n;i++) hash[val[i]]=i;
for(i=1;i<=n;i++){
ans+=sum(val[i]+1);
update(val[i],1);
}
int swp=0;
for(i=1;i<=n;i++){
if(val[i]!=i){
swp++;
int p=hash[i];
int now=val[i];
swap(val[p],val[i]);
hash[now]=p;
}
}
printf("%d\n%lld\n",swp,ans);
}
}



你可能感兴趣的:(ZOJ)