UVa 11489 - Integer Game

题目: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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值