• [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:

    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)

    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.

    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).

    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,并且按照最小字典序输出。 

    题解:

    求最大的k,就是求最大的lcm,这个用dp就可以解决。

    如何输出方案,因为题目要求字典序最小,所以环的数量也要最少,那么我们对k分解一下质因数,得到每个环的长度。

    然后将所有环按从小到大排序,最前面的数就直接输出。

     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("
    ");
    63   }
    64   return 0;
    65 }
  • 相关阅读:
    php函数注释
    组件化开发
    7.哪些工具可以帮助查找bug或进行静态分析
    6.Python中内存是如何管理的?
    5.Python是怎么解释的?
    4.pickling 和unpickling是什么?
    3.PEP 8是什么?
    2.Python是什么?使用Python的好处是什么?
    Redis介绍及字符串操作
    字符串转换为二进制
  • 原文地址:https://www.cnblogs.com/huangdalaofighting/p/8343573.html
Copyright © 2020-2023  润新知