HDU 4259 Double Dealing

 

给你n张卡片,分给k个人,从1-n轮流分。然后,重新把卡片放在一起。第1个人的放在最上边,后面的依次放下面。 再重新分,再放,问多少次后会恢复原样。

10 3

第一次

10 7 4 1 8 5 2 9 6 3

第二次

3 2 1 10 9 8 7 6 5 4

第三次

4 7 10 3 6 9 2 5 8 1

第四次

1 2 3 4 5 6 7 8 9 10

 

 1 #include <algorithm>

 2 #include <iostream>

 3 #include <cstring>

 4 #include <cstdio>

 5 #define LL long long

 6 using namespace std;

 7 int a[1000], vis[1000];

 8 LL gcd(LL a,LL b)

 9 {

10     return b==0?a:gcd(b,a%b);

11 }

12 int main()

13 {

14     int i,j,n,k,t;

15     while(~scanf("%d%d",&n,&k))

16     {

17         LL ans,sum=1;

18         if(n==0&&k==0)

19             break;

20         t=0;

21         for(i=0;i<k&&i<n;i++)

22             for(j=(n-i-1)/k*k+i;j>=0;j-=k)

23                 a[t++]=j;

24         memset(vis,0,sizeof(vis));

25         for(i=0;i<n;i++)

26         {

27             int x=i;

28             ans=0;

29             while(!vis[x])

30             {

31                 ans++;

32                 vis[x]=1;

33                 x=a[x];

34             }

35             if(ans)

36                 sum=sum/gcd(sum,ans)*ans;

37         }

38         printf("%I64d\n",sum);

39     }

40 }

 

 

 

你可能感兴趣的:(double)