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