题目:S和T两个人轮流从一个数字中取出一位扔掉(S先取),谁无法取就结束(包括被对方取完),
已知一个1000位以内的数字,判断谁获胜。
分析:数论。分类讨论。
将数字分成三组:mod3=0,mod3=1,mod3=2;
结论1:如果最后只有一个数字不是3的倍数,可以把它当做3的倍数;
结论2:如果所有数字位数数字和是3的倍数,则每次(除最后)只能取走mod3=0的数字(3的倍数);
此时mod3=0的数字为奇数则S获胜,否则T获胜;
结论3:如果所有数字位数数字和不是3的倍数,则第一次要取走余数和总和相同的数字才能合法;
余下的取法同上,此时mod3=0的数字为偶数则S获胜,否则T获胜;
说明:登录也很卡(⊙v⊙)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char deal(char buf[])
{
int n = strlen(buf);
int size[3], sum = 0;
size[0] = size[1] = size[2] = 0;
for (int i = 0; i < n; ++ i) {
buf[i] = (buf[i]-'0')%3;
size[buf[i]] ++;
sum = (sum+buf[i])%3;
}
if (sum) { // S 初始删除多出来的3的倍数的余数
if (size[sum] == 0) { // S 初始失败
return 'T';
}else if (size[1] + size[2] <= 2) {
return n%2?'S':'T';
}else {
return size[0]%2?'T':'S';
}
}else { // S 初始删除多出来的3的倍数
if (size[1] + size[2] <= 1) {
return n%2?'S':'T';
}else {
return size[0]%2?'S':'T';
}
}
}
int main()
{
int T;
char buf[1001];
while (~scanf("%d",&T))
for (int t = 1; t <= T; ++ t) {
scanf("%s",buf);
printf("Case %d: %c\n",t,deal(buf));
}
return 0;
}