天天看點

hdu 4529 Double Dealing (置換群)

# include <stdio.h>
# include <algorithm>
# include <string.h>
using namespace std;
__int64 gcd(__int64 a,__int64 b)
{
    if(b==0)
        return a;
    return gcd(b,a%b);
}
int main()
{
    int n,k,i,j,vis[810],m,num[810],x;
    __int64 res,cot;
    while(~scanf("%d%d",&n,&k),n+k)
    {
        m=1;
        for(i=1; i<=k&&i<=n; i++) //第一次分完牌
            for(j=(n-i)/k*k+i; j>0; j-=k)
                num[m++]=j;
        res=1;
        memset(vis,0,sizeof(vis));
        for(i=1; i<=n; i++)
        {
            if(vis[i])
                continue;
            x=i;
            cot=0;
            while(1)
            {
                vis[x]=1;
                cot++;
                x=num[x];
                if(i==x)
                    break;
            }
            res=res/gcd(res,cot)*cot;
        }
        printf("%I64d\n",res);
    }
    return 0;
}