UVA-3882(递推)
UVA



题意:约瑟夫环。给定n,k,m,人从1排到n,从1报数,第一次先杀报到m的人,之后杀报到k的人。
思路:先看经典的约瑟夫问题。n个人,从0号到n-1号围坐成一个圈。从0报数报到k-1的人死。之后第k人继续从0开始报数。如此直到只剩一人,则胜利。问胜利人的编号是多少。
第1轮:n-1人:0,1,2……k-2,k,k+1……n-2,n-1,第k-1人死。之后形成了一个n-1个人的新的约瑟夫环。
整理-:k,k+1……n-2,n-1,0,1,2……k-2。新的约瑟夫环。重新排序号得
n-1人:0,1,……n-2-k,n-1-k,n-k,n-k+1,n-k+2……n-2。
第2轮:……
……
假设第2轮排x的人,在第1轮排x',x'=(x+k)%n。由此我们得知n-1个人的编号对应的n人约瑟夫环的编号。
想要知道第n个人的编号,就要得到n-1人的编号,就要得到n-2的编号,……,最后的约瑟夫环中,只有一人。编号为0。所以递推到n人就知道胜利者的编号了。
回到此题。此题是第一次先杀m,之后在杀报道k的。那么就从1个人开始递推,递推到n-1人。之后最后一次递推是x'=(x+m)%n。这样得到的是0到n-1编号的人的胜利者。最后再把得到的编号加一就行了。
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int n, k, m; 7 8 int main() 9 { 10 while(scanf("%d%d%d", &n, &k, &m), n+k+m){ 11 int ans = 0; 12 for (int i = 2; i < n; i++){ 13 ans = (ans+k)%i; 14 } 15 ans = (ans+m)%n; 16 printf("%d\n", ans+1); 17 } 18 return 0; 19 }

浙公网安备 33010602011771号