总结一下poj上的约瑟夫问题。
POJ 3517 And Then There Was One http://poj.org/problem?id=3517
最朴实的约瑟夫问题,网上一搜攻略一大把。最关键是理解f = (f+m)%n的含义
1 #include <stdio.h> 2 3 int main() 4 { 5 // freopen("input", "r", stdin); 6 int m, k, n; 7 while(scanf("%d %d %d", &n, &k, &m), n && k && m) 8 { 9 int f = 0; 10 for(int i=2 ; i<n ; i++) 11 f = (f + k) % i; 12 printf("%d\n", (f+m) % n + 1); 13 } 14 }
POJ 2244 Eeny Meeny Moo http://poj.org/problem?id=2244
由于限定了n的范围很小,可以预处理。
他一开始就把第一城市去掉了,所以相当于对n-1进行处理(21行);要求保留第二个城市最后,但由于我们处理的是n-1,所以相当于保留第0个位置(16行)。
1 #include <stdio.h> 2 const int MAXN = 151; 3 int a[MAXN]; 4 5 int main() 6 { 7 // freopen("input", "r", stdin); 8 int n; 9 for(n=2 ; n<MAXN ; n++) 10 { 11 for(int k=1 ; ; k++) 12 { 13 int f = 0; 14 for(int i=2 ; i<=n ; i++) 15 f = (f+k)%i; 16 if(f == 0) 17 { a[n] = k; break; } 18 } 19 } 20 while(scanf("%d", &n), n) 21 printf("%d\n", a[n-1]); 22 }
POJ 1781 In Danger http://poj.org/problem?id=1781
一开始觉得这题不是裸约瑟夫吗?但是写了朴素算法后TLE。
看了网上讨论说朴素算法不行,需要找规律避免“%"运算。
本来准备打表的,但打表后得1 1 3 1 3 5 7 1 3 5 7 9 11 13 15 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 1 3 5 7 ……
可以看出每次减去2^k最后*2-1即可
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 int main() 6 { 7 // freopen("input", "r", stdin); 8 char ch; 9 int n; 10 while(scanf("%de%c\n", &n, &ch), n || ch-'0') 11 { 12 for(int i=0 ; i<ch-'0' ; i++) 13 n *= 10; 14 for(int i=1 ; i<n ; i<<=1) 15 n -= i; 16 printf("%d\n", n*2-1); 17 } 18 }
今天的题好水。。。再写点别的