zoukankan      html  css  js  c++  java
  • Cutting Game(POJ 2311)

    • 原题如下:
      Cutting Game
      Time Limit: 1000MS   Memory Limit: 65536K
      Total Submissions: 5721   Accepted: 2083

      Description

      Urej loves to play various types of dull games. He usually asks other people to play with him. He says that playing those games can show his extraordinary wit. Recently Urej takes a great interest in a new game, and Erif Nezorf becomes the victim. To get away from suffering playing such a dull game, Erif Nezorf requests your help. The game uses a rectangular paper that consists of W*H grids. Two players cut the paper into two pieces of rectangular sections in turn. In each turn the player can cut either horizontally or vertically, keeping every grids unbroken. After N turns the paper will be broken into N+1 pieces, and in the later turn the players can choose any piece to cut. If one player cuts out a piece of paper with a single grid, he wins the game. If these two people are both quite clear, you should write a problem to tell whether the one who cut first can win or not.

      Input

      The input contains multiple test cases. Each test case contains only two integers W and H (2 <= W, H <= 200) in one line, which are the width and height of the original paper.

      Output

      For each test case, only one line should be printed. If the one who cut first can win the game, print "WIN", otherwise, print "LOSE".

      Sample Input

      2 2
      3 2
      4 2
      

      Sample Output

      LOSE
      LOSE
      WIN
    • 题解:这种会发生分割的游戏,也可以计算Grundy值
      当w*h的纸张分成两张时,假设所分得的纸张的Grundy值分别为g1和g2,则这两张纸对应的状态的Grundy值可以表示为gxor g2
      在Nim中,不论有几堆石子,初始状态是怎样的,只要xor的结果相同,那么对胜负是没有影响的。这里也是同样的,只要Grundy值相同,即便发生分割,只要对分割后的各部分取xor,就可以用这一个Grundy值来代表几个游戏复合而成的状态,Grundy值也可以同样计算(也可以说,这是因为xor运算的结合律)。
      另,切割纸张时,一旦切割出了长或宽为1的纸张,下一步就一定能够切割出1*1的纸张,所以可以知道此时必败。因此,切割纸张时,总要保证长和宽至少为2(无论如何都不能保证时,就是必败态。此时根据Grundy值的定义,不需要特别处理其Grundy值也是0)。
    • 代码:
       1 #include<cstdio>
       2 #include<cstring>
       3 #include<set>
       4 
       5 using namespace std;
       6 
       7 const int MAX_WH=200;
       8 int w, h;
       9 int men[MAX_WH+1][MAX_WH+1];
      10 
      11 int grundy(int w, int h)
      12 {
      13     if (men[w][h]!=-1) return men[w][h];
      14     set<int> S;
      15     for (int i=2; w-i>=2; i++) S.insert(grundy(i, h) ^ grundy(w-i, h));
      16     for (int i=2; h-i>=2; i++) S.insert(grundy(w, i) ^ grundy(w, h-i));
      17     int res=0;
      18     while (S.count(res)) res++;
      19     return men[w][h]=res;
      20 }
      21 
      22 int main()
      23 {
      24     memset(men, -1, sizeof(men));
      25     while (~scanf("%d %d", &w, &h))
      26     {
      27         if (grundy(w, h)!=0) puts("WIN");
      28         else puts("LOSE");
      29     }
      30 }
  • 相关阅读:
    python操作MySQL数据库(转)
    python3.3.2中的关键字(转)
    HashMap的键值需要注意什么?
    为什么基本类型不能做为HashMap的键值?
    怎么确保一个集合不能被修改?
    Iterator和 ListIterator有什么区别?
    Iterator怎么使用?有什么特点?
    迭代器Iterator是什么?
    哪些集合类是线程安全的?
    Queue的element()和peek()方法有什么区别?
  • 原文地址:https://www.cnblogs.com/Ymir-TaoMee/p/9791828.html
Copyright © 2011-2022 走看看