zoukankan      html  css  js  c++  java
  • Uva 1378

    1378 - A Funny Stone Game

    Time limit: 3.000 seconds

    The funny stone game is coming. There are n piles of stones, numbered with 0, 1, 2,..., n - 1. Two persons pick stones in turn. In every turn, each person selects three piles of stones numbered i, j, k (i < j, j $ leq$k and at least one stone left in pile i). Then, the person gets one stone out of pile i, and put one stone into pile j and pile k respectively. (Note: if j = k, it will be the same as putting two stones into pilej). One will fail if he can't pick stones according to the rule.

    David is the player who first picks stones and he hopes to win the game. Can you write a program to help him?

    The number of piles, n, does not exceed 23. The number of stones in each pile does not exceed 1000. Suppose the opponent player is very smart and he will follow the optimized strategy to pick stones.

     

    Input 

    Input contains several cases. Each case has two lines. The first line contains a positive integer n ( 1 $ leq$ n$ leq$ 23) indicating the number of piles of stones. The second line contains n non-negative integers separated by blanks, S0,...Sn-1 ( 0 $ leq$ Si $ leq$ 1000), indicating the number of stones in pile 0 to pile n - 1respectively.

    The last case is followed by a line containing a zero.

     

    Output 

    For each case, output a line in the format ``Game t: i j k". t is the case number. i, j and k indicates which three piles David shall select at the first step if he wants to win. If there are multiple groups of i, jand k, output the group with the minimized lexicographic order. If there are no strategies to win the game,i, j and k are equal to -1.

     

    Sample Input 

    4
    1 0 1 100
    3
    1 0 5
    2
    2 1
    0
    

     

    Sample Output 

     

    Game 1: 0 2 3
    Game 2: 0 1 1
    Game 3: -1 -1 -1
    
    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4124
    题意:略。
    思路:分解的方法,《解析一类组合游戏》中的第一题。几句话看了几个小时,这个伤不起。
       后来想到了,相同局面的化简,顿时明白了这种分解的方法。
    子局面,和下一个局面。
    堪称经典题。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cstdlib>
     5 using namespace std;
     6 
     7 int SG[25];
     8 bool use[120];
     9 void prepare()
    10 {
    11     int i,j,s;
    12     SG[1]=0;
    13     for(i=2;i<=23;i++)
    14     {
    15         memset(use,false,sizeof(use));
    16         for(j=1;j<i;j++)
    17             for(s=1;s<i;s++)
    18             {
    19                 use[ SG[j]^SG[s] ]=true;
    20             }
    21         for(j=0;;j++)
    22             if(use[j]==false)
    23             {
    24                 SG[i]=j;
    25                 break;
    26             }
    27     }
    28 }
    29 int main()
    30 {
    31     int n,i,j,ans,s,T=0;
    32     int f[25];
    33     bool flag;
    34     prepare();
    35     while(scanf("%d",&n)>0)
    36     {
    37         if(n==0)break;
    38         for(i=0 ,ans=0;i<n;i++)
    39         {
    40             scanf("%d",&f[i]);
    41             if(f[i]&1)
    42             {
    43                 ans=ans^SG[n-i];
    44             }
    45         }
    46         printf("Game %d: ",++T);
    47         if(ans==0)
    48         {
    49             printf("-1 -1 -1
    ");
    50             continue;
    51         }
    52         flag=false;
    53         for(i=0;i<n;i++)
    54         {
    55             if(flag==true) break;
    56             if(f[i]==0)continue;
    57             for(j=i+1;j<n;j++)
    58             {
    59                 if(flag==true) break;
    60                 if(f[j]==0)continue;
    61                 for(s=i+1;s<n;s++)
    62                 {
    63                     if(f[s]==0)continue;
    64                     if( (SG[n-i]^SG[n-j]^SG[n-s])== ans)
    65                     {
    66                         printf("%d %d %d
    ",i,j,s);
    67                         flag=true;
    68                         break;
    69                     }
    70                 }
    71             }
    72         }
    73 
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    您认为做好测试用例设计工作的关键是什么?
    系统测试的策略
    在C/C++中static有什么用途?
    BUG管理工具的跟踪过程
    详细的描述一个测试活动完整的过程。
    输出一个整数的每一位,如:123的每一位是1 , 2 , 3
    编写代码模拟三次密码输入的场景。 最多能输入三次密码,密码正确,提示“登录成功”,密码错误, 可以重新输 入,最多输入三次。三次均错,则提示退出程序
    获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列
    求一个整数,在内存当中存储时,二进制1的个数。
    求两个正整数的最大公约数
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3438338.html
Copyright © 2011-2022 走看看