Codeforces Round #383 (Div. 2) C(遞迴找環求最小公倍數)
阿新 • • 發佈:2018-12-24
題目連結
題目大意:表示意思有點繞,什麼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);
}
}