UVa 11489

来源:互联网 发布:招商银行外汇交易软件 编辑:程序博客网 时间:2024/06/03 21:04

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


原创粉丝点击