POJ2369 置換群大水題
阿新 • • 發佈:2018-12-23
世界真的很大
與這張圖片不符,這是一道很基礎的置換群的題了,並不難,只要清楚置換群的概念,不會超過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打標記表示哪些已經有“歸屬”的迴圈節了,最後所有的迴圈節長度取最小公倍數就是答案啦!