CF1487-B. Cat Cycle
题意
家中有两只猫,这两只猫有n个睡觉的地方分别标号为 1 , 2 , . . . , n 1,2,...,n 1,2,...,n。一开始第一只猫(后称为A)在标号为n的位置睡觉,第二只猫(后称为B)在标号为1的位置睡觉。
之后每过一个小时, A A A会挪到 i − 1 i-1 i−1这个位置睡觉(若 i = 0 i=0 i=0那么就挪动到 n n n这个位置),而 B B B则会挪到 i + 1 i+1 i+1这个位置睡觉(若 i = n + 1 i=n+1 i=n+1则挪动到 1 1 1这个位置)。但是这两只猫不会睡在一起,当两只猫移动到同一个位置的时候, B B B会避开 A A A到下一个位置去。
问第k个小时的时候B在什么位置睡觉。
思路
当 n n n为偶数的时候,这两只猫总会错开不会同时到达同一个位置;当 n n n为奇数的时候,这两只猫会每 n 2 n\over2 2n小时到达同一个位置一次。
当到达同一个位置的时候,本质上 B B B在重合位置编号的基础上加上 1 1 1,所以第 k k k个小时的时候 B B B就相当于在原本的位置(就是不考虑重合的时候 B B B要到下一个位置)的基础上加上 k − 1 n 2 {k-1}\over{n\over2} 2nk−1,减一是因为第一个位置是不在第一个 n 2 n\over2 2n范围内的。那么这只猫最终的位置就是 ( k − 1 + k − 1 n 2 ) % n + 1 (k-1+\frac{k-1}{n\over2})\%n+1 (k−1+2nk−1)%n+1。前半部分的 k − 1 k-1 k−1是想要将这n个位置的编号从 0 0 0开始方便取模运算,若不从 0 0 0开始也可以采取下面的写法: t = ( k + k − 1 n 2 ) % n , t = = 0 ? n : t t=(k+\frac{k-1}{n\over2})\%n,t==0?n:t t=(k+2nk−1)%n,t==0?n:t.
AC代码
#include <cstdio>
void solve() {
int n, k;
scanf("%d %d", &n, &k);
if (n & 1) {
printf("%d\n", (k - 1 + (k - 1) / (n / 2)) % n + 1);
} else {
printf("%d\n", (k - 1) % n + 1);
}
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}