约瑟夫环(模板)

第一种题:(●ˇ∀ˇ●),

题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1073

①:最好理解的放法,但时间复杂度过高! 2187 ms 5616 KB

 

所参考博客:https://blog.csdn.net/kangroger/article/details/39254619

 1 #include<stdio.h>
 2 #include<cstring>
 3 using namespace std;
 4 int people[1000100];//表示人. 
 5 int main()
 6 {
 7     int n,m;
 8     while (scanf("%d%d",&n,&m)!=EOF)
 9     {
10         int cnt=0;//标记出列的有多少个 
11         memset(people,1,sizeof(people));
12         for (int i=1,j=0; ;i++)//j表示报数是多少 ,i表示第几个人 
13         {
14             if (people[i])//表示i没出列 
15             {
16                 j++;
17                 if (j==m)//如果报数和要求的数相同
18                 {
19                     ++cnt;
20                     j=0;//初始 
21                     people[i]=0;//标记第i个人出列 
22                  }
23                  if (cnt==n)//如果已经全部出列,那就结束 
24                  {
25                      printf("%d\n",i);
26                      break;
27                   } 
28             }
29             if (i==n)
30             {
31                 i=0;
32             }
33         }
34     }
35     return 0;
36 }
View Code

 

②复杂度低的方法  31 ms  1708 KB        超级短小精悍!

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int n, m, i, s = 0;
 5     while (scanf("%d%d", &n, &m)!=EOF)
 6     {
 7             for (i = 2; i <= n; i++)
 8         {
 9             s = (s + m) % i;
10         }
11             printf ("%d\n", s+1);
12     }
13 }
View Code

 ③这应该是最厉害的了 时间更短

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int main(){
 7     unsigned long long i,j,n,k;
 8     cin>>n>>k;
 9     long long y=k%2;
10     long long x=2,t=0;
11     long long z1,z2;
12     z1=y;
13     z2=x;
14     while(x<=n){
15     z1=y;
16     z2=x;
17     t=(x-y)/(k-1);
18     if(t==0) t++;
19     y=y+t*k-((y+t*k)/(x+t))*(x+t);
20     x+=t;
21     }
22     cout<<(z1+(n-z2)*k)%(n)+1<<endl;
23 }
View Code

 

第二种题:(●ˇ∀ˇ●)

根据第一种题改编,由于题目n小,所以可以用第一种题的“简单”方法

题目链接:https://www.nowcoder.com/acm/contest/121/D

 

 1 #include<stdio.h>
 2 #include<cstring>
 3 using namespace std;
 4 int people[30];//表示人. 
 5 int main()
 6 {
 7     int n,m;
 8     while (scanf("%d%d",&n,&m)!=EOF)
 9     {
10         int cnt=0;//标记出列的有多少个 
11         memset(people,1,sizeof(people));
12         for (int i=1,j=0; ;i++)//j表示报数是多少 ,i表示第几个人 
13         {
14             if (people[i])//表示i没出列 
15             {
16                 j++;
17                 if (j==m)//如果报数和要求的数相同
18                 {
19                     ++cnt;
20                     j=0;//初始 
21                     people[i]=0;//标记第i个人出列 
22                     if (cnt==1)
23                     printf("%d",i);
24                     else
25                     printf(" %d",i);
26                  }
27                  if (cnt==n)//如果已经全部出列,那就结束 
28                  {
29                      printf("\n");
30                      break;
31                   } 
32             }
33             if (i==n)
34             {
35                 i=0;
36             }
37         }
38     }
39     return 0;
40 }
View Code

 

posted @ 2018-05-13 15:24  jealous-boy  阅读(201)  评论(0编辑  收藏  举报