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

 

 

 

你可能感兴趣的:(double)