题目链接
题目大意:表示意思有点绕,什么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);
}
}