HDU 4259 Double Dealing

题意: 给N个人依次分卡片,然后从的第一个人到最后一个人依次拿走全部的卡片,问最少经过多少次,可以使得卡片回复到原来的次数。

分析:求出每个卡片循环到原来位置的最少次数,在一个循环节中,每个卡片的循环次数相同,求出这些循环次数的最小公倍数即可,(输入要用%I64d,用%lld wa了好长时间)

#include<stdio.h>
#include<string.h>
#define maxn 1000
long long next[maxn];
long long a[maxn];
long long gcd(long long x, long long y)
{
   if(!x||!y) return x > y ? x : y;
       for (long long t; t = x % y; x = y, y = t);
   return y;
}
long long multi(long long a[],long long n)//下标从零开始
{
    long long  c=a[0],i;
    for(i=1;i<n;i++)
    c=a[i]/gcd(a[i],c)*c;
    return c;
}
long long v[1005];
long long ti[1005];
int main()
{
    long long i,n,m,j,k,tt,tmp;
    long long top,tot;
    while(scanf("%I64d%I64d",&n,&k)!=EOF)
    {
        if(n==0&&k==0)
        break;
        if(n<=k)
        {
            printf("1\n");
            continue;
        }
        tt=1;
        i=n-(n-1)%3;
        tmp=i;
        for(i=1;i<=k;i++)
            for(j=n-(n-i)%k;j>=1;j-=k)
                    next[j]=tt++;
        top=0;
        memset(v,0,sizeof(v));
        for(i=1;i<=n;i++)
            if(!v[i])
            {
                v[i]=1;
                tot=1;
                tmp=next[i];
                while(tmp!=i)
                {
                    v[tmp]=1;
                    tmp=next[tmp];
                    tot++;
                }
                ti[top++]=tot;
            }
        printf("%I64d\n",multi(ti,top));
    }
    return 0;
}

 

posted @ 2012-08-25 21:58  'wind  阅读(239)  评论(0编辑  收藏  举报