现在的位置: 首页 > 综合 > 正文

ZOJ 1039 Number Game

2019年04月14日 ⁄ 综合 ⁄ 共 2117字 ⁄ 字号 评论关闭

记得很久前写过,博弈的题目大同小异,要注意的就是两点:

 

1、状态的表示

 

2、状态之间的转换:只要能达到必败态,就是必胜态。反之就是必败态。起点为必败态。

 

另外,数组作为参数传递时是指针传递。

 

  1. #include <cstdio>
  2. #include <string>
  3. int cs, n;
  4. int list[21];
  5. int move[21], len;
  6. int b[600000];
  7. inline int map ( int seq[] )
  8. {
  9.     int i;
  10.     int ret = 0;
  11.     for ( i = 2; i < 21; i ++ )
  12.     {
  13.         if ( seq[i] )
  14.             ret |= 1 << i - 2;
  15.     }
  16.     return ret;
  17. }
  18. int dfs ( int src[], int op )
  19. {
  20.     int i, k;
  21.     //print ( src, op );
  22.     src[op] = 0;
  23.     for ( i = 2; i + op <= 20; i ++ )
  24.     {
  25.         if ( src[i] == 1 )
  26.             continue;
  27.         for ( k = 1; k <= 20 && k * i + op <= 20; k ++ )
  28.             src[k * i + op] = 0;
  29.     }
  30.     //print ( src, op );
  31.     int state = map ( src );
  32.     if ( b[state] )
  33.         return b[state];
  34.     int dst[21];
  35.     for ( i = 2; i <= 20; i ++ )
  36.     {       
  37.         memcpy ( dst, src, sizeof ( dst ) );
  38.         //print ( dst, op );
  39.         if ( dst[i] && dfs ( dst, i ) == -1 )
  40.         {
  41.             //printf ( "%d %d/n", state, 1 );
  42.             b[state] = 1;
  43.             return 1;
  44.         }
  45.     }
  46.     //printf ( "%d %d/n", state, -1 );
  47.     b[state] = -1;
  48.     return -1;
  49. }
  50. void init ()
  51. {
  52.     memset ( b, 0, sizeof ( b ) );
  53.     b[0] = -1;
  54.     memset ( list, 0, sizeof ( list ) );
  55.     scanf ( "%d", &n );
  56.     int i, x;
  57.     for ( i = 0; i < n; i ++ )
  58.     {
  59.         scanf ( "%d", &x );
  60.         list[x] = 1;
  61.     }
  62. }
  63. void proc ()
  64. {
  65.     int i;
  66.     //int state = map ( list );
  67.     len = 0;
  68.     int src[21];
  69.     for ( i = 2; i < 21; i ++ )
  70.     {
  71.         memcpy ( src, list, sizeof ( list ) );
  72.         if ( src[i] && dfs ( src, i ) == -1 )
  73.         {           
  74.             move[len ++] = i;
  75.         }
  76.     }
  77.     if ( len == 0 )
  78.     {
  79.         b[map ( list )] = -1;
  80.         printf ( "There is no winning move./n/n" );
  81.     }
  82.     else
  83.     {
  84.         b[map ( list )] = 1;
  85.         printf ( "The winning moves are:" );
  86.         for ( i = 0; i < len; i ++ )
  87.         {
  88.             printf ( " %d", move[i] );
  89.         }
  90.         printf ( "./n/n" );
  91.     }
  92.     //print ();
  93. }
  94. int main ()
  95. {
  96.     //freopen ( "in.txt", "r", stdin );
  97.     scanf ( "%d", &cs );
  98.     int i;
  99.     for ( i = 0; i < cs; i ++ )
  100.     {
  101.         printf ( "Scenario #%d:/n", i + 1 );
  102.         init ();
  103.         proc ();
  104.     }
  105.     return 0;
  106. }
【上篇】
【下篇】

抱歉!评论已关闭.