POJ 3590

题意:给出一个整数n,叫你给出1到n的某个序列经过k次置换后能还原,求这样最大的k,如果存在多种序列满足要求。

则必须求出字典序最小的那个序列。

一个轮换必须经过它的大小的次数的置换才能还原,那么这个序列的k其实就是它的所有轮换的大小的最小公倍数。至于怎么求

最小序列,可以通过素数分解来完成。

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define MAXN 104
 5 using namespace std;
 6 __int64 dp[MAXN][MAXN];
 7 __int64 gcdmax[MAXN];
 8 __int64 Div[MAXN];
 9 int prime[25] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
10 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
11 int cnt;
12 
13 __int64 gcd(__int64 x, __int64 y)
14 {
15   if (min(x,y) == 0)return max(x,y);
16   return gcd(y,x%y);  
17 }
18 
19 void prepare()
20 {
21     for (int i(1); i<=100; ++i) {
22         dp[i][1] = i;
23     }
24     
25     for (int i(2); i<=100; ++i) {
26         for (int j(2); j<=i; ++j) {
27             for (int k(1); k<i && (i-k)>=(j-1); ++k) {
28                 dp[i][j] = max(dp[i][j],dp[i-k][j-1]*k/gcd(dp[i-k][j-1],k));
29             }
30         }
31     }
32     
33     for (int i(1); i<=100; ++i) {
34         for (int j(1); j<=i; ++j) {
35             gcdmax[i] = max(gcdmax[i],dp[i][j]);
36         }
37     }
38 }
39 
40 void deal(__int64 num)
41 {
42     cnt = 0;
43     for (int i(0); i<25; ++i) {
44         if (num%prime[i])continue;
45         Div[cnt] = 1;
46         while (num%prime[i] == 0) {
47             Div[cnt] *= prime[i];
48             num /= prime[i];
49         }
50         ++cnt;
51     }
52 }
53 
54 
55 int main()
56 {
57     int t;
58     prepare();
59     scanf("%d",&t);
60     while (t--) {
61         int n;
62         scanf("%d",&n);
63         cout<<gcdmax[n];
64         deal(gcdmax[n]);
65         sort(Div,Div+cnt);
66         int sum = 0;
67         for (int i(0); i<cnt; ++i) {
68             sum += Div[i];
69         }
70         sum = n - sum;
71         for (int i(1),j(0),k(0); i<=n; ++i) {
72             if (sum) {
73                 cout<<" "<<i;
74                 sum--;
75             } else {
76                 for (j = 1; j<Div[k]; ++j) {
77                     cout<<" "<<i+j;
78                 }
79                 ++k;
80                 cout<<" "<<i;
81                 i += (j-1);
82             }
83         }
84         cout<<endl;
85     }
86     return 0;
87 }
posted on 2012-06-28 14:04  Dev-T  阅读(316)  评论(0编辑  收藏  举报