首页 > 代码库 > HDU 4259

HDU 4259

虽然知道是置换,却很久没有思路。忽然想到,由初始状态A经过变换后回到A状态,应该是不停循环可重复的。于是,猜想数字的位置也是重复循环的。拿了个例子验证了一下,某然是这样。例如第二个10,3的例子有1-》4-》3-》10-》1.

于是,可以按照上题的方法求解了。

#include <iostream>#include <algorithm>#include <cstdio>#define LL __int64#define N 800using namespace std;int num[N+1];bool vis[N+1];int stack[N+1],top;LL gcd(LL a,LL b){	if(b==0) return a;	return gcd(b,a%b);}int main(){	int n,k;	while(scanf("%d%d",&n,&k),n||k){		if(n<=k){			printf("1\n");			continue;		}		memset(vis,false,sizeof(vis));		int counted=0;		for(int i=1;i<=n;i++){   //此处是可以优化的,可以通过计算来做。 			if(!vis[i]){				int tmp=i;				top=0;				while(tmp<=n){					vis[tmp]=true;					stack[++top]=tmp;					tmp+=k;				}				while(top>0){					num[++counted]=stack[top];					top--;				}			}		}		memset(vis,false,sizeof(vis));		top=0;		for(int i=1;i<=n;i++){			if(!vis[i]){				int k=i;				counted=0;				while(!vis[k]){					vis[k]=true;					k=num[k];					counted++;				}				stack[++top]=counted;			}		}		LL ans=(LL)stack[top--];		for(int i=top;i>0;i--){			ans=ans*((LL)stack[i]/gcd(ans,(LL)stack[i]));		}		printf("%I64d\n",ans);	}	return 0;}

  

HDU 4259