[POJ 3590]The shuffle Problem

Description

Any case of shuffling of n cards can be described with a permutation of 1 to n. Thus there are totally n! cases of shuffling. Now suppose there are 5 cards, and a case of shuffle is <5, 3, 2, 1, 4>, then the shuffle will be:ios

Before shuffling:1, 2, 3, 4, 5
The 1st shuffle:5, 3, 2, 1, 4
The 2nd shuffle:4, 2, 3, 5, 1
The 3rd shuffle:1, 3, 2, 4, 5
The 4th shuffle:5, 2, 3, 1, 4
The 5th shuffle:4, 3, 2, 5, 1
The 6th shuffle:1, 2, 3, 4, 5(the same as it is in the beginning)spa

You'll find that after six shuffles, the cards' order returns the beginning. In fact, there is always a number m for any case of shuffling that the cards' order returns the beginning after m shuffles. Now your task is to find the shuffle with the largest m. If there is not only one, sort out the one with the smallest order.code

Input

The first line of the input is an integer T which indicates the number of test cases. Each test case occupies a line, contains an integer n (1 ≤ n ≤ 100).blog

Output

Each test case takes a line, with an integer m in the head, following the case of shuffling.
 排序

Sample Input

2
1
5

Sample Output

1 1
6 2 1 4 5 3

題目大意:

給你一個n,問你長度爲n的排列裏面,經過置換變成本身,即 p^k=p,求最大的k,而且按照最小字典序輸出。 ip

題解:

求最大的k,就是求最大的lcm,這個用dp就能夠解決。get

如何輸出方案,由於題目要求字典序最小,因此環的數量也要最少,那麼咱們對k分解一下質因數,獲得每一個環的長度。input

而後將全部環按從小到大排序,最前面的數就直接輸出。string

 1 //Never forget why you start
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<algorithm>
 8 using namespace std;
 9 typedef long long lol;
10 lol n,m,f[105][105],t,tmp,ans[105],p[25]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,91,97};
11 lol gcd(lol a,lol b){
12   if(b==0)return a;
13   else return gcd(b,a%b);
14 }
15 lol lcm(lol a,lol b){
16   return a*b/gcd(a,b);
17 }
18 void dp(lol n){
19   lol i,j,k;
20   for(i=1;i<=n;i++){
21     f[i][1]=i;
22     for(j=2;j<=i;j++)
23       for(k=1;k<i;k++)
24     f[i][j]=max(f[i][j],lcm(f[k][j-1],i-k));
25   }
26   for(i=1;i<=n;i++)
27     for(j=1;j<=n;j++)
28       ans[i]=max(ans[i],f[i][j]);
29 }
30 lol cnt,sum[105];
31 void make(lol x){
32   lol i;cnt=0;
33   for(i=0;i<25;i++){
34     if(x%p[i])continue;
35     sum[++cnt]=1;
36     while(x%p[i]==0){
37       x/=p[i];
38       sum[cnt]*=p[i];
39     }
40   }
41 }
42 int main(){
43   lol i,j,k;
44   dp(100);
45   scanf("%lld",&t);
46   while(t--){
47     scanf("%lld",&n);
48     make(ans[n]);
49     sort(sum+1,sum+cnt+1);
50     tmp=0;
51     for(i=1;i<=cnt;i++)tmp+=sum[i];
52     printf("%lld",ans[n]);
53     for(i=1;i<=n-tmp;i++)
54       printf(" %lld",i);
55     k=n-tmp;
56     for(i=1;i<=cnt;i++){  
57       for(j=2;j<=sum[i];j++)  
58     printf(" %lld",k+j);  
59       printf(" %lld",k+1);  
60       k+=sum[i];  
61     }
62     printf("\n");
63   }
64   return 0;
65 }
相關文章
相關標籤/搜索