CodingTrip - 휴대용 프로 그래 밍 대회 - 네 번 째 문제 - 깃발 쟁탈

깃발 을 빼앗다
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 411    Accepted Submission(s): 194
Problem Description
 
   
小时候玩过一种小游戏,夺旗。游戏规则:共有N组旗子,每组旗子数量已知,两个玩家轮流拔旗,每次只能选某一组,拔掉一定数量的旗子,至少需要拔一个,拔掉旗子之后,还可以将该组旗子中余下的任意多个旗子中任选几个放到其它的任意一组或几组里。一堆旗子被拔空后就不能再往此处插旗了。先无法拔旗的人为输者。 假设每次都是你先拔旗子,且每个player都足够聪明,现在给你旗子的组数、每组旗子的数量,请判断出你能否获胜。 例如:如果最开始有4组旗子,旗子个数分别为3 1 4 2,而你想决定要先拿走第三组旗子中的两个旗子,旗子个数变为3 1 2 2,然后他可以使旗子组达到的状态有以下几种: 3 1 2 2(不移动) 4 1 1 2(移动到第一组一个) 3 2 1 2(移动到第二组一个) 3 1 1 3(移动到第四组一个) 4 2 0 2(移动到第一组一个,第二组一个) 4 1 0 3(移动到第一组一个,第四组一个) 3 2 0 3(移动到第二组一个,第四组一个) 5 1 0 2(全部移动到第一组) 3 3 0 2(全部移动到第二组) 3 1 0 4(全部移动到最后)
 

Input
 
   
可能有多组测试数据(测试数据组数不超过1000) 每组测试数据的第一行是一个整数,表示N(1<=N<=10) 第二行是N个整数分别表示该组旗子中旗子的数量。(每组旗子数目不超过100) 当输入的N为0时,表示输入结束输出对于每组测试数据。
 

Output
 
   
Win表示你可以获胜,输出Lose表示你必然会败。
 

Sample Input
 
   
3 2 1 3 2 1 1 0
 

Sample Output
 
   
Win Lose
刚看到时感觉很熟悉,不就是拿石子问题吗。。。。博弈,,,但是又和以往的不同,,,就是,“拔掉旗子之后,还可以将该组旗子中余下的任意多个旗子中任选几个放到其它的任意一组或几组里。”这句话。最后没做出来。。。

PS: n=1的情况不用考虑,考虑n=2的情况,注意到当两堆石子的数量一样的时候,无论先手做何操作,只要后手模仿先手的操作即可回到两堆石子数量一样的状态,类比n=2的情况,在n=4的时候只要有两对石子的个数是一样的也必败,后手同样只要模仿先手的操作即可,以此类推。

那么当石子数不是两两配对的时候呢?那么只要将石子个数排序,然后把最多的一堆石子变成和最少的一堆石子一样多,再将多余出来的石子分配给中间的堆,使其两两配对即可,至于为什么一定可以将其两两配对,只要将中间石子两两的差投影到y轴即可证明。

那么n为偶数的情况就解决了,至于n为奇数的情况,只要将最多的那堆取完,再把多余的石子分配给剩下的使其两两配对即可,证明同上。

#include
#include
int cmp(const void *a,const void *b)
{
    return *(int *)a>*(int *)b?1:-1;
}
int k[15];
int main()
{
    int i,n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)
            break;
        for(i=0;i=n)
            printf("Lose
"); else printf("Win
"); } return 0; }

좋은 웹페이지 즐겨찾기