# POJ 1143 Number Game

N(N<=20)个数字组成的状态，想办法寻找能对应这个状态的hash函数，于是可以有一个20位的数(unsigned int 的低20位)表示，这位为1表示这位在输入数字中，为0表示不在输入数字中。则可定义一个数组record表示状态（有数字可选、没有数字可选、不确定），数组大小为（1<<20），数组的每一个下标是一个状态（表示一组输入），下标对应的值为状态。

   1: #include <iostream>
   2: #include <memory.h>
   3: using namespace std;
   4: const int NUM_SIZE = 21;
   5: int record[1<<20];
   6:
   7: inline unsigned int myMap(bool s[])
   8: {
   9:     unsigned int index=0;
  10:     for (int i=2; i<NUM_SIZE; i++)
  11:     {
  12:         if (s[i])    index |= 1;
  13:         index <<= 1;
  14:     }
  15:     return (index>>1);
  16: }
  17:
  18: bool dfsNext(bool s[], const int pos)
  19: {
  20:     bool curr[NUM_SIZE];
  21:     memcpy(curr, s, NUM_SIZE);
  22:     curr[pos] = false;
  23:     for (int i=2; i+pos<NUM_SIZE; i++)
  24:     {
  25:         if (!curr[i])
  26:             curr[i+pos] = false;
  27:     }
  28:     unsigned index = myMap(curr);
  29:     if (record[index]>0)
  30:         return true;
  31:     else if (record[index]<0)
  32:         return false;
  33:
  34:     for (int i=2; i<NUM_SIZE; i++)
  35:     {
  36:         if (curr[i] && (!dfsNext(curr, i)))
  37:         {
  38:             record[index] = 1;
  39:             return true;
  40:         }
  41:     }
  42:     record[index] = -1;
  43:     return false;
  44: }
  45: int main()
  46: {
  47:     int n=0;
  48:     bool source[NUM_SIZE];
  49:     int cases = 1;
  50:     while (cin>>n && n!=0)
  51:     {
  52:         memset(source, false, sizeof(source));
  53:         for (int i=0; i<n; i++)
  54:         {
  55:             int num=0;
  56:             cin >> num;
  57:             source[num] = true;
  58:         }
  59:         unsigned int index=myMap(source);
  60:         int count=0;
  61:         int res[NUM_SIZE];
  62:         memset(res, 0, sizeof(res));
  63:         for (int i=2; i<NUM_SIZE; i++)
  64:         {
  65:             if (source[i] && (!dfsNext(source, i)))
  66:                 res[count++] = i;
  67:         }
  68:         cout << "Test Case #" << cases++ << endl;
  69:         if (count==0)
  70:         {
  71:             record[index] = -1;
  72:             cout << "There's no winning move." << endl;
  73:         }
  74:         else if (count>0)
  75:         {
  76:             cout << "The winning moves are:";
  77:             for (int i=0; i<count; i++)
  78:                 cout << ' ' << res[i];
  79:             cout << endl;
  80:         }
  81:         cout << endl;
  82:     }
  83:     return 0;
  84: }
06-01 343
10-06 1129

08-03 271
10-02 42
09-23 602
12-15 35
08-11 320
08-27 851
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客