题目地址:http://codeforces.com/contest/742/problem/C 题意:我看了好多别人的博客的对于题意的理解,结合他们的代码我认为这道题的意思应该是每个数要都能经过t步以后到达一个点,再经过t步到达起点。 思路:看这些数能否构成一个或多个环(包括自环),如果存在不能成环的数就输出-1,否则一定存在一个最小的t。
如果当前环中元素的个数为奇数,则 x->x->x 当前的t=元素个数 如果当前环中元素的个数为偶数,则 x->y->x (y为中间的数)当前的t=元素个数/2 然后再把每个环的 t 求出他们的最小公倍数就是最小的 t,对于每个环都满足的t。
#include <iostream> #include <cstring> #include <string> #include <queue> #include <vector> #include <map> #include <set> #include <stack> #include <cmath> #include <cstdio> #include <algorithm> #define LL long long #define N 110 #define M 50010 #define inf 0x3f3f3f3f using namespace std; const LL mod = 1e9 + 7; const double eps = 1e-9; LL num[N], pre[N]; LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a%b); } LL lcm(LL a, LL b) { return a*b / gcd(a, b); } int main() { cin.sync_with_stdio(false); LL n, flag, ans, cnt, sum; while (cin >> n) { memset(pre, 0, sizeof(pre)); for (int i = 1; i <= n; i++) { cin >> num[i]; } flag = 1; sum = 0; for (int i = 1; i <= n&&flag; i++) { if (!pre[i]) { ans = i; cnt = 0; while (pre[num[ans]] == 0) { pre[num[ans]] = ans; ans = num[ans]; cnt++; } if (pre[ans] == 0 || ans != i) { flag = 0; } else { if (cnt % 2) { if (sum == 0) { sum = cnt; } else { sum = lcm(sum, cnt); } } else { if (sum == 0) { sum = cnt / 2; } else { sum = lcm(sum, cnt / 2); } } } } } if (flag) { cout << sum << endl; } else { cout << -1 << endl; } } return 0; }