HDU 4259

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

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

#include <iostream>
#include <algorithm>
#include <cstdio>
#define LL __int64
#define N 800
using 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;
}

  

posted @ 2014-10-15 21:27  chenjunjie1994  阅读(171)  评论(0编辑  收藏  举报