poj2369 Permutations ——置换群

时间:2023-03-09 00:14:46
poj2369 Permutations ——置换群

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找循环节么。很神奇的样子。

多多模拟一下,严格的证明貌似还要好好看一下近世代数。

嗨,中村