hdu 4259 Double Dealing

思路:

找每一个数的循环节,注意优化!!

每次找一个数的循环节时,记录其路径,下次对应的数就不用再找了……

代码如下:

 

 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\n",ans);
53     }
54     return 0;
55 }
View Code

 

 

 

posted @ 2013-09-02 21:32  _随心所欲_  阅读(262)  评论(0编辑  收藏  举报