题意:小明有编号1-n的n双袜子。每天他会在衣柜里选取编号最小的袜子穿,并在晚上把这天穿的袜子放到篮子里。当他发现篮子里的袜子的数量为n-1时他会清洗篮子里的袜子,袜子晾干后会在第二天的晚上被收进衣柜。请问第k天的早晨他会穿编号为几的袜子?
题意不难理解,最开始使用vector/set去模拟这个过程可以得出答案。但是问题是题目给出的k的范围是1e18,很明显这么大的数据是不可以直接模拟的。所以就要想其他的办法,是不是有规律?打表看一下发现果然是的。
n = 6 123456 12345 12346 12345 12346
n = 7 1234567 123456 123457 123456 123457
……
每种n都会先有1-n的一节,之后周期2(n-1)进行循环,每个长度为n-1的周期内,奇数周期时是1…n-2, n-1,偶数时为1…n-2,n。
不过n=2时是一种特殊情况,打表发现是121212,所以根据k的奇偶性判断即可。
这道题的关键是要根据n k的范围排除直接模拟,想到打表找规律。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n, ans, case_;
ll k;
int main()
{
while(scanf("%d %lld", &n, &k) != EOF)
{
case_++;
if(n == 2)//特判
{
if(k % 2 == 0)
ans = 2;
else
ans = 1;
}
else
{
if(k <= n)
ans = k;
else
{
k -= n;
if(k % (n-1) == 0)//正好在周期的末尾
{
if((k / (n - 1)) % 2 == 0)//偶数周期 1...n-2 n
ans = n;
else
ans = n-1;
}
else
{
ans = k % (n-1);
}
}
}
printf("Case #%d: %d\n", case_, ans);
}
return 0;
}