UVA 1452 - Jump
dp[i] = (dp[i-1] + k) % i;
初始化倒数第二个出去的 dp[2] = (k+1)%2;
约瑟夫环。对于一个n个人,没k个踢出去的约瑟夫环。踢出一个人后,环成了
0, 1, 2, ... ,k-2, k, k+1, ... ,n
对其从k为起点重新编号
n-k+1, n-k+2, ... ,n-1, 0, 1, 2, ...n-k
这样变成了一个(n-1, k)的约瑟夫环问题。
于是得到转移方程dp[i] = (dp[i-1] + k) % i;
而题目还要去得出倒数第二个出去的和倒数第三个出去的。
其转移如上,但是初始化倒数第二个出去的 dp[2] = (k+1)%2;
初始化倒数第三个出去的 dp[3] = (k+2)%3;
#include <bits/stdc++.h>
int n, k;
int dp0[1000000+5];
int dp1[1000000+5];
int dp2[1000000+5];
int main () {
int T;
for (scanf("%d", &T); T>0; T--) {
scanf("%d%d", &n, &k);
dp0[1] = 0;
for (int i=2; i<=n; i++) {
dp0[i] = (k + dp0[i-1]) % i;
}
dp1[2] = (k+1)%2;
for (int i=3; i<=n; i++) {
dp1[i] = (k + dp1[i-1]) % i;
}
dp2[3] = (k+2)%3;
for (int i=4; i<=n; i++) {
dp2[i] = (k + dp2[i-1]) % i;
}
printf ("%d %d %d\n", dp2[n]+1, dp1[n]+1, dp0[n]+1);
}
return 0;
}