1. 程式人生 > >POJ2369 置換群大水題

POJ2369 置換群大水題

這裡寫圖片描述
世界真的很大
與這張圖片不符,這是一道很基礎的置換群的題了,並不難,只要清楚置換群的概念,不會超過5分鐘AC,所以其實用這道題來最終檢測對置換群的概念理解是非常不錯的,嗯嗯。
先來說一下題意:給你一串數列1~n,但是是打亂順序的,問換回正常升序最少需要多少次,說清楚一點,最少要“置換”多少次,這樣。
那麼很簡單,找置換裡的迴圈節吧,每個迴圈節的元素個數決定了需要多少次才能還原,那麼直接取lcm就行了。
完整程式碼:

 #include<stdio.h>
int a[100010],n,f[1000010],vis[100010];
int gcd(int
a,int b) { if(b == 0) return a; return gcd(b,a%b); } int lcm(int a,int b) { return a/gcd(a,b)*b; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); f[a[i]]=i; } int ans=1; for(int i=1;i<=n;i++) { int
j=i,cnt=0; while(vis[j]==0) { cnt++; vis[j]=1; j=f[j]; } if(cnt) ans=lcm(ans,cnt); } printf("%d",ans); }

超級短是不是!用f陣列記錄原序列每一項與正常序列的每一項的關係,然後由每一項出發去標記他所屬的迴圈節,cnt記錄迴圈節長度,vis打標記表示哪些已經有“歸屬”的迴圈節了,最後所有的迴圈節長度取最小公倍數就是答案啦!