link:http://poj.org/problem?id=2369
置换群,最简单的那种。
找所有数字循环节的最小公倍数。
/* ID: zypz4571 LANG: C++ TASK: permutations.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <algorithm> #include <queue> #include <deque> #include <queue> #include <list> #include <map> #include <set> #include <vector> #include <utility> #include <functional> #include <fstream> #include <iomanip> #include <sstream> #include <numeric> #include <cassert> #include <ctime> #include <iterator> const int INF = 0x3f3f3f3f; ][] = {{-,},{,},{,-},{,},{-,-},{-,},{,-},{,}}; using namespace std; ]; ]; int gcd(int x, int y) { ? x : gcd(y, x%y); } int lcm(int x, int y) { return x/gcd(x,y)*y; } int main ( int argc, char *argv[] ) { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif ios::sync_with_stdio(false); int n; while (~scanf("%d", &n)) { ; i < n; ++i) scanf(); ; memset(flag, false, sizeof(flag)); ; i <= n; ++i) { , pos = i; if (!flag[pos]) { for (; !flag[a[pos]]; ++sum) { flag[a[pos]] = true; pos = a[pos]; } ans = lcm(ans, sum); } } printf("%d\n", ans); } return EXIT_SUCCESS; } /* ---------- end of function main ---------- */
开始有一点不理解,仔细想一想就明白了。把上面的程序模拟一下这个样例:
1 | 2 | 3 | 4 | 5 |
4 | 1 | 5 | 2 | 3 |
2 | 4 | 1 | ||
1 | 2 | 4 |
比如,我在对1找循环节的时候,过程中出现了4,那么将来,就不用对4找循环节了。
这么想:1 经过4到达1,那么4一定可以经过1到达4.并且4的循环节必然和1相等!
因为在对1找循环节的时候,你遇到了4,那么这就相当于在这个时候对4找循环节么。很神奇的样子。
多多模拟一下,严格的证明貌似还要好好看一下近世代数。
嗨,中村