找回密码
 欢迎注册
查看: 13053|回复: 7

[原创] 划数游戏

[复制链接]
发表于 2009-10-15 18:26:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
在如下的4*4方格中,2人
依次划去1~4个相邻的数(可以是纵横或斜45度),比如:0102,0408,030609
但当划的路径中已经有数被划去,则不能再划.比如02已划,则不能010203
划去最后一个方格的数者判负,请问先后手谁有必胜的策略?

01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 16
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 07:08:52 | 显示全部楼层
这个题目用计算机很简单.状态只有最多$2^16$种
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 07:35:24 | 显示全部楼层

重新排版

$[(1,2,3,4),(5,6,7,8),(9,10,11,12),(13,14,15,16)]$
■ 用数学公式LaTeX重新排版
  1. 01 02 03 04
  2. 05 06 07 08
  3. 09 10 11 12
  4. 13 14 15 16
复制代码
■ 用code标签重新排版,可避免英文字母或数字对不齐现象
  1. +----+----+----+----+
  2. | 01 | 02 | 03 | 04 |
  3. +----+----+----+----+
  4. | 05 | 06 | 07 | 08 |
  5. +----+----+----+----+
  6. | 09 | 10 | 11 | 12 |
  7. +----+----+----+----+
  8. | 13 | 14 | 15 | 16 |
  9. +----+----+----+----+
复制代码
■ 再手工加上表格线

01020304
05060708
09101112
13141516

■ 直接用表格排版(如果表格比较小,应限定table=xxx;如果将table居中,其内的所有单元格均居中)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-10-16 08:16:32 | 显示全部楼层
有几种必胜和必败的形
必胜:
倒数第3步:曲3和不相连的1,方4,不是直4的双直2,对方下步无论如何不能给出直1

必败:
倒数第3步:直2,直3,直4,对方下步总能给出直1
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 16:20:53 | 显示全部楼层
N*N的格子,
N=1,2,4先手败
N=3,5先手胜

  1. #include <string.h>
  2. #include <assert.h>
  3. #include <stdlib.h>
  4. #include <vector>
  5. using namespace std;
  6. #define N 4
  7. #define BITS (N*N)
  8. typedef unsigned int SET;
  9. #define BIT(x,y)  ((x)+(y)*N)
  10. char result[1<<BITS];
  11. vector<SET> lines;
  12. void init_lines()
  13. {
  14.     int i;
  15.     for(i=0;i<BITS;i++){///single element
  16.         SET s=1<<i;
  17.         lines.push_back(s);
  18.     }
  19.     for(i=0;i<N;i++){
  20.         int x=i,y=0;
  21.         SET s=1<<BIT(x,y);
  22.         while(++y<N){
  23.             s|=1<<BIT(x,y);
  24.             lines.push_back(s);
  25.         }
  26.     }
  27.     for(i=0;i<N;i++){
  28.         int x=0,y=i;
  29.         SET s=1<<BIT(x,y);
  30.         while(++x<N){
  31.             s|=1<<BIT(x,y);
  32.             lines.push_back(s);
  33.         }
  34.     }
  35.     for(i=0;i<N;i++){
  36.         int x=i,y=0;
  37.         SET s=1<<BIT(x,y);
  38.         while(--x>=0&&++y<N){
  39.             s|=1<<BIT(x,y);
  40.             lines.push_back(s);
  41.         }
  42.     }
  43.     for(i=0;i<N;i++){
  44.         int x=i,y=0;
  45.         SET s=1<<BIT(x,y);
  46.         while(++x<N&&++y<N){
  47.             s|=1<<BIT(x,y);
  48.             lines.push_back(s);
  49.         }
  50.     }
  51.     for(i=1;i<N-1;i++){
  52.         int x=i,y=N-1;
  53.         SET s=1<<BIT(x,y);
  54.         while(--x>=0&&--y>=0){
  55.             s|=1<<BIT(x,y);
  56.             lines.push_back(s);
  57.         }
  58.     }
  59.     for(i=1;i<N-1;i++){
  60.         int x=i,y=N-1;
  61.         SET s=1<<BIT(x,y);
  62.         while(++x<N&&--y>=0){
  63.             s|=1<<BIT(x,y);
  64.             lines.push_back(s);
  65.         }
  66.     }
  67. }
  68. #define FAIL (char)-1
  69. #define SUCC (char)1
  70. char search(SET s)
  71. {
  72.     int i;
  73.     if(result[s]!=0)
  74.         return result[s];
  75.     for(i=0;i<lines.size();i++){
  76.         if((s&lines[i])==lines[i]){
  77.             char r=search(s&~lines[i]);
  78.             if(r==FAIL)
  79.                 break;
  80.         }
  81.     }
  82.     if(i==lines.size()){
  83.         result[s]=FAIL;
  84.     }else{
  85.         result[s]=SUCC;
  86.     }
  87.     return result[s];
  88. }

  89. int main()
  90. {
  91.     init_lines();
  92.     result[0]=SUCC;
  93.     int i;
  94.     for(i=0;i<BITS;i++){
  95.         result[1<<i]=FAIL;
  96.     }
  97.     char r=search((1<<BITS)-1);
  98.     if(r==SUCC){
  99.         printf("First win\n");
  100.     }else{
  101.         printf("First fail\n");
  102.     }
  103. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-10-16 19:37:49 | 显示全部楼层
阅读理解中
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-10-16 20:14:20 | 显示全部楼层
没太看懂,把cpp翻译成标准C,执行结果
58 (才这么多,代表什么?)
First fail

  1. //#include <string.h>
  2. //#include <assert.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. //#include <vector>
  6. //using namespace std;
  7. #define N 4
  8. #define BITS (N*N)
  9. typedef unsigned int SET;
  10. #define BIT(x,y)  ((x)+(y)*N)
  11. #define lines_push_back(s) lines[p++]=s
  12. char result[1<<BITS];
  13. //vector<SET> lines;
  14. SET lines[10000000L];
  15. int lines_size=0;
  16. void init_lines()
  17. {
  18.     int i;
  19.     int p=0;
  20.     for(i=0;i<BITS;i++){///single element
  21.         SET s=1<<i;
  22.         lines_push_back(s);
  23.     }
  24.     for(i=0;i<N;i++){
  25.         int x=i,y=0;
  26.         SET s=1<<BIT(x,y);
  27.         while(++y<N){
  28.             s|=1<<BIT(x,y);
  29.             lines_push_back(s);
  30.         }
  31.     }
  32.     for(i=0;i<N;i++){
  33.         int x=0,y=i;
  34.         SET s=1<<BIT(x,y);
  35.         while(++x<N){
  36.             s|=1<<BIT(x,y);
  37.             lines_push_back(s);
  38.         }
  39.     }
  40.     for(i=0;i<N;i++){
  41.         int x=i,y=0;
  42.         SET s=1<<BIT(x,y);
  43.         while(--x>=0&&++y<N){
  44.             s|=1<<BIT(x,y);
  45.             lines_push_back(s);
  46.         }
  47.     }
  48.     for(i=0;i<N;i++){
  49.         int x=i,y=0;
  50.         SET s=1<<BIT(x,y);
  51.         while(++x<N&&++y<N){
  52.             s|=1<<BIT(x,y);
  53.             lines_push_back(s);
  54.         }
  55.     }
  56.     for(i=1;i<N-1;i++){
  57.         int x=i,y=N-1;
  58.         SET s=1<<BIT(x,y);
  59.         while(--x>=0&&--y>=0){
  60.             s|=1<<BIT(x,y);
  61.             lines_push_back(s);
  62.         }
  63.     }
  64.     for(i=1;i<N-1;i++){
  65.         int x=i,y=N-1;
  66.         SET s=1<<BIT(x,y);
  67.         while(++x<N&&--y>=0){
  68.             s|=1<<BIT(x,y);
  69.             lines_push_back(s);
  70.         }
  71.     }
  72.     lines_size=p;
  73.     printf("%d\n",lines_size);
  74. }
  75. #define FAIL (char)-1
  76. #define SUCC (char)1
  77. char search(SET s)
  78. {
  79.     int i;
  80.     if(result[s]!=0)
  81.         return result[s];
  82.     for(i=0;i<lines_size;i++){
  83.         if((s&lines[i])==lines[i]){
  84.             char r=search(s&~lines[i]);
  85.             if(r==FAIL)
  86.                 break;
  87.         }
  88.     }
  89.     if(i==lines_size){
  90.         result[s]=FAIL;
  91.     }else{
  92.         result[s]=SUCC;
  93.     }
  94.     return result[s];
  95. }

  96. int main()
  97. {
  98.     init_lines();
  99.     result[0]=SUCC;
  100.     int i;
  101.     for(i=0;i<BITS;i++){
  102.         result[1<<i]=FAIL;
  103.     }
  104.     char r=search((1<<BITS)-1);
  105.     if(r==SUCC){
  106.         printf("First win\n");
  107.     }else{
  108.         printf("First fail\n");
  109.     }
  110. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 21:33:11 | 显示全部楼层
很简单,我们用一个N*N比特的二进制数表示方格当前的状态.对于每个格子对应比特是1表示这个格子还没有被划掉,0表示被划掉.所以初始状态为((1<<BITS)-1),也就是所有格子没有被划掉.
数组result[]用来保存每个方格状态是先手胜还是后手胜.先手胜结果保存为SUCC,后手胜结果保存为FAIL.
函数search用来计算每个方格状态是先手胜还是后手胜.先查询result[]判断是否已经计算过.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-24 21:02 , Processed in 0.046215 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表