Vijos 约瑟夫问题10E100版 (又是找规律+高精)

描述

n个人排成一圈。从某个人开始,按顺时针方向依次编号。从编号为1的人开始顺时针“一二一”报数,报到2的人退出圈子。这样不断循环下去,圈子里的人将不断减少。由于人的个数是有限的,因此最终会剩下一个人。试问最后剩下的人最开始的编号。

格式

输入格式

一个正整数n,表示人的个数。输入数据保证数字n不超过100位。

输出格式

一个正整数。它表示经过“一二一”报数后最后剩下的人的编号。

样例1

样例输入1

9

样例输出1

3

限制

各个测试点1s

提示

样例说明
当n=9时,退出圈子的人的编号依次为:
2 4 6 8 1 5 9 7
最后剩下的人编号为3

来源

Matrix67 根据经典问题改编

 

先打个表找规律

 

 1 #include<cstdio>
 2 #include<ctime>
 3 #include<cstring>
 4 int vis[10001]= {0};
 5 int main() {
 6     freopen("output.txt","w",stdout);
 7     for(int z=1; z<=10000; z++) {
 8         memset(vis,0,sizeof(vis));
 9         int n,count=0;
10         n=z;
11         int now=1,next=1,kill=0;
12         while(count<n-1) {
13             do
14                 next=(next-1+1)%n+1;
15             while(vis[next]);
16             if(kill) {
17                 count++;
18                 vis[now]=1;
19                 kill=0;
20             } else
21                 kill=1;
22             now=next;
23         }
24         for(int i=1; i<=n; i++)
25             if(!vis[i])
26                 printf("%d,",i);
27     }
28     return 0;
29 }
暴力

 

找到规律后 再用高精 (有点恶心)

 

 1 /*
 2     当 2^i<=n<=2^(i+1) 时
 3     输出 (n-2^i)*2+1
 4 */
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<iostream>
 8 #define MAXN 1010
 9 
10 using namespace std;
11 
12 int a[MAXN],y[MAXN],b[MAXN],c[MAXN],cnt;
13 
14 char s[MAXN];
15 
16 inline void chuli() {
17     int len=strlen(s);
18     y[0]=len;
19     for(int i=len-1;i>=0;i--) y[++cnt]=s[i]-48;
20 }
21 
22 inline bool pd() {
23     if(y[0]>a[0]) return false;
24     else if(y[0]<a[0]) return true;
25     else {
26         for(int i=y[0];i>=1;i--) {
27             if(y[i]>a[i]) return false;
28             if(y[i]<a[i]) return true;
29         }
30     }
31     return false;
32 }
33 
34 inline void mul() {
35     for(int i=0;i<=a[0];i++) b[i]=a[i];
36     a[0]++;
37     for(int i=1;i<=a[0];i++) a[i]*=2;
38     for(int i=1;i<=a[0];i++) {
39         if(a[i]>=10) {
40             a[i+1]+=a[i]/10;
41             a[i]%=10;
42         }
43     }
44     while(a[0]>0&&!a[a[0]]) a[0]--;
45 }
46 
47 inline void div() {
48     c[0]=y[0];
49     for(int i=1;i<=y[0];i++) {
50         c[i]+=y[i]-b[i];
51         if(c[i]<0) {
52             c[i+1]--;
53             c[i]+=10;
54         } 
55     }
56     while(c[0]>0&&!c[c[0]]) c[0]--;
57     memset(a,0,sizeof a);
58     for(int i=0;i<=c[0];i++) a[i]=c[i];
59 }
60 
61 int main() {
62     cin>>s;
63     chuli();
64     a[0]=1;
65     a[1]=1;
66     while(!pd()) mul();
67     div();
68     mul();
69     if(!a[0]) a[0]++;
70     a[1]++;
71     for(int i=1;i<=a[0];i++) {
72         if(a[i]>=10) {
73             if(i==a[0]) a[0]++;
74             a[i+1]+=a[i]/10;
75             a[i]%=10;
76         }
77     }
78     while(a[0]>0&&!a[a[0]]) a[0]--;
79     for(int i=a[0];i>=1;i--) printf("%d",a[i]);
80     printf("\n");
81     return 0;
82 }
代码

 

posted @ 2017-07-03 18:03  拿叉插猹哈  阅读(161)  评论(0编辑  收藏  举报