首先将扑克牌进行一次置换,然后分解出所有的循环节,所有循环节的扑克牌个数的最小公倍数即为答案
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL long long
int n,k;
LL d[850],ct;
int vis[850];
int a[850]; int dfs(int x)
{
if(!vis[a[x]])
{
ct++;
vis[a[x]]=1;
dfs(a[x]);
}
}
int main()
{
while(scanf("%d%d",&n,&k)==2)
{
if(!n&&!k)break;
int t=0;
memset(vis,0,sizeof(vis));
for(int i=k; i>=1; i--)
{
for(int j=i; j<=n; j+=k)
a[++t]=j;
}
for(int i=1; i<=n/2; i++)
{
int tp=a[i];
a[i]=a[n+1-i];
a[n+1-i]=tp;
}
int p=0;
for(int i=1; i<=n; i++)
{
if(!vis[i])
{
ct=1;
vis[i]=1;
dfs(i);
d[p++]=ct;
}
}
if(p==1) printf("%I64d\n",d[0]);
else
{
LL x=d[0]/__gcd(d[0],d[1])*d[1];
for(int i=2; i<p; i++)
{
x=x/__gcd(x,d[i])*d[i];
}
printf("%I64d\n",x);
} }
return 0;
}