首先将扑克牌进行一次置换,然后分解出所有的循环节,所有循环节的扑克牌个数的最小公倍数即为答案
#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 ",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 ",x); } } return 0; }