题目大意:将一个1~n的环形排列变成升序的,最少需要几次操作?每次操作可以交换任意两个数字。
题目分析:枚举出1的位置。贪心策略:每次操作都保证至少一个数字交换到正确位置上。
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; int a[2000],head,tail,n,b[505]; bool ok(int id,int d) { for(int i=0;i<n;++i){ int p=(id+d*b[i]-d+n)%n; if(p!=i) return false; } return true; } int getAns(int id,int d) { for(int i=0;i<n;++i) b[i]=a[i]; int res=0; while(!ok(id,d)) { for(int i=0;i<n;++i){ int p=(id+d*b[i]-d+n)%n; if(i!=p){ ++res; swap(b[i],b[p]); } } } return res; } void solve() { head=0,tail=n; while(a[head]!=1) a[tail++]=a[head++]; for(int i=0;i<n;++i) a[i]=a[head++]; int ans=100000000; for(int i=0;i<n;++i) ans=min(ans,min(getAns(i,1),getAns(i,-1))); printf("%d ",ans); } void read() { for(int i=0;i<n;++i) scanf("%d",a+i); } int main() { ///freopen("UVA-10570 Meeting with Aliens.txt","r",stdin); while(scanf("%d",&n)&&n) { read(); solve(); } return 0; }