1. 程式人生 > >Codeforces Round #383 (Div. 2) C(遞迴找環求最小公倍數)

Codeforces Round #383 (Div. 2) C(遞迴找環求最小公倍數)

題目連結
題目大意:表示意思有點繞,什麼owww的,通俗的來講就是找環,問的是滿足x走到y的步數可以讓y走到x。
分析
那麼如果x走到x是一個偶數n,說明可以用n/2走到y且y不等於x
然後再用n/2步數走到x。這個環的權值就是n/2;
如果n是一個奇數,那麼這個環的權值就是n。
然後就是把所有環的權值都找到並且求他們的最小公倍數。就得到答案啦

#include<stdio.h>
#include<string.h>
long long a[1010];
int vis[1010];    //用來標記點是否遍歷過
int flog;           //用來記錄是否有不成環的點
long long b[1010]; long long gcd(long long aa,long long bb) { return bb==0?aa:gcd(bb,aa%bb); } long long dfs(int u,int t,int now) { if(now==u&&vis[u]) //找到環 return t; if(vis[now]) //找不到環 return -1; vis[now]=1; dfs(u,t+1,a[now]); } int main() { int n; scanf
("%d",&n); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); flog=0; int cut=0; for(int i=1;i<=n;i++) { if(vis[i]) continue; b[cut++]=dfs(i,0,i); if(b[cut-1]==-1) { printf("-1\n"); flog=1
; break; } if(b[cut-1]%2==0) //偶數步數減半 b[cut-1]/=2; } if(!flog) { long long aa=b[0]; long long bb; for(int i=1;i<cut;i++) //求最小公倍數 { bb=aa*b[i]; aa=gcd(aa,b[i]); aa=bb/aa; } printf("%lld\n",aa); } }