思路:
找每一个数的循环节,注意优化!!
每次找一个数的循环节时,记录其路径,下次对应的数就不用再找了……
代码如下:
1 #include<iostream> 2 #include<cstdio> 3 #include<stack> 4 #include<cstring> 5 #define ll __int64 6 using namespace std; 7 int vis[801],to[801],an[801]; 8 stack<int>p; 9 ll gcd(ll a,ll b) 10 { 11 if(a<b) swap(a,b); 12 while(b){ 13 ll t=a; 14 a=b; 15 b=t%b; 16 } 17 return a; 18 } 19 int main() 20 { 21 int i,j,n,k,a,b; 22 ll ans,num; 23 while(scanf("%d%d",&n,&k)&&(n+k)){ 24 j=1; 25 while(!p.empty()) p.pop(); 26 for(i=1;i<=k;i++){ 27 a=i; 28 while(a<=n){ 29 p.push(a); 30 a+=k; 31 } 32 while(!p.empty()){ 33 b=p.top(); 34 to[b]=j++; 35 p.pop(); 36 } 37 } 38 memset(vis,0,sizeof(vis)); 39 ans=1; 40 for(i=1;i<=n;i++){ 41 if(vis[i]==0){ 42 num=1; 43 a=to[i]; 44 while(a!=i){ 45 vis[a]=1; 46 a=to[a]; 47 num++; 48 } 49 ans=num/gcd(num,ans)*ans; 50 } 51 } 52 printf("%I64d ",ans); 53 } 54 return 0; 55 }