题意:
n个人,x可以打电话给crushx 然后说: "Oww...wwf" (w重复t次),如果t > 1 那么crushx 打给crushcrushx 然后说: "Oww...wwf" (w重复t-1次 ),循环下去直到t=1,到达的人被称为Joon-Joon。求最小的t,使得任意x开始,存在y是Joon-Joon,而当 y开始打电话时,x是Joon-Joon。没有则输出-1。
分析:需要注意的是题目要求的是求出符合每个人的循环节,就是说如果有一个人不能打电话最后传回到自己那么答案就是-1。如果一个人始终是打给自己的,那么无论t只要多大只要大于1就都适合。然后就是求每个人最小是几个t打电话能打回自己,然后求这么多个t的最小公倍数。注意如果先乘两个数在除两个数的最大公约数的话会答案会在乘的时候溢出,导致答案错误。是要用循环模拟一下每个人的打电话过程就可以最终算出每个人的t了。
#include<bits/stdc++.h>
using namespace std;
int a[105], vis[105];
int main()
{
int n;
while(cin >> n)
{
int flag = 0;
long long ans = 1;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
int next = a[i], cou = 1, st = i;
vis[i]++;
while(st != next)
{
vis[next]++;
if(vis[next] == 2)
{
flag = 1;
break;
}
cou++;
next = a[next];
}
if(ans == -1)
{
if(cou % 2 == 0)
ans = cou / 2;
else
ans = cou;
}
else
{
if(cou % 2 == 0)
cou = cou / 2;
long long gcd = __gcd(ans, (long long)cou);
ans = ans * cou / gcd;
}
if(flag == 1)
break;
}
if(flag)
cout << -1 << endl;
else
cout << ans << endl;
}
return 0;
}