• HDU 4259 Double Dealing 【离散数学】


    Problem Description
    Take a deck of n unique cards. Deal the entire deck out to k players in the usual way: the top card to player 1, the next to player 2, the kth to player k, the k+1st to player 1, and so on. Then pick up the cards – place player 1′s cards on top, then player 2, and so on, so that player k’s cards are on the bottom. Each player’s cards are in reverse order – the last card that they were dealt is on the top, and the first on the bottom.
    How many times, including the first, must this process be repeated before the deck is back in its original order?
     
    Input
    There will be multiple test cases in the input. Each case will consist of a single line with two integers, n and k (1≤n≤800, 1≤k≤800). The input will end with a line with two 0s.
     
    Output
    For each test case in the input, print a single integer, indicating the number of deals required to return the deck to its original order. Output each integer on its own line, with no extra spaces, and no blank lines between answers. All possible inputs yield answers which will fit in a signed 64-bit integer.
     
    Sample Input
    1 3 10 3 52 4 0 0
     
    Sample Output
    1 4 13
     

    思路:以10 3 为例:题意很好理解,
    1》通过一次变换,数值变化情况是
    1 2 3 4 5 6 7 8 9 10
    10 7 4 1 8 5 2 9 6 3
    通过一次变化,下标变化情况是
    1 2 3 4 5 6 7 8 9 10
    4 7 10 3 6 9 2 5 8 1
    2》由此可以看出来:位置的变化有如下规律:
    1->4->3->10->1;
    2->7->2;
    5->6->9->8->5;
    可以知道这一串的变化周期是一样的,想变化到以前的位置次数也是相同的;
    对于不同串的变换周期,要想最少nn次变化回来,那么要满足nn是他们的最小公倍数;
    3》对于求下标和容易知道最后一个数n在的第几列,可以依次把该列的都求出来
    那么根据这一列找到他右边的这里列最后的值即n+1-3,那么可以将此列的值全部求出来;
    4》这是离散数学的知识点轮换;
    1->4->3->10->1; 这称为一个轮换;
    (1->4->3->10->1)*(2->7->2)*(5->6->9->8->5)
    也就是3个轮换,每一个轮换中的元素无论执行多少次相同的置换都不会和其他轮换相交
    所以结果就是 lcm(4,2,3)=4

    代码如下:

    #include<stdio.h>
    #include<string.h>
    int a[1000], vis[1000];
    long long gcd(long long a, long long b) 
    { 
        return a ? gcd(b%a, a) : b; 
    }
    int main()
    {
        int i, j, n, k, t;
        while(scanf("%d%d", &n, &k)!=EOF)
        {
             if(n==0&&k==0)
                 break;
            t=0; 
            for(i=0; i<k&&i<n; i++)
                for(j=(n-i-1)/k*k+i; j>=0; j-=k)
                    a[t++]=j;
             memset(vis, 0, sizeof(vis));
             long long ans, lcmnum=1; 
            for(i=0; i<n; i++)
            {
                int x=i;
                ans=0; 
                while(!vis[x])
                {
                    ans++;
                    vis[x]=1; 
                    x=a[x];
                }
                if(ans) 
                    lcmnum=lcmnum/gcd(lcmnum, ans)*ans;
            }
            printf("%I64d\n", lcmnum);
        }
    }
  • 相关阅读:
    安装伪分布的Hadoop时SHUTDOWN_MSG: Shutting down NameNode at xxx并不一定是namenode格式化失败
    ubuntu安装与卸载java
    hadoop之Hive部署
    Hive中生成随机唯一标识ID的方法
    利用sqoop将hive数据导入导出数据到mysql
    利用sqoop将hive数据导入导出数据到mysql
    linux中sqoop实现hive数据导入到mysql
    linux中sqoop部署以及实现mysql数据导入hive
    Altium Designer如何创建类,如何修改线宽
    Altium Designer中画pcb如何隐藏和显示地线
  • 原文地址:https://www.cnblogs.com/Hilda/p/2656864.html
Copyright © 2020-2023  润新知