魔术数字游戏
2011-10-18 19:25
190 查看
魔术数字游戏
【问题描述】
填数字方格的游戏有很多种变化,如下图所示的4×4方格中,我们要选择从数字1到16来填满这十六个格子(Aij,其中i=1..4,j=1..4)。为了让游戏更有挑战性,我们要求下列六项中的每一项所指定的四个格子,其数字累加的和必须为34:
1.四个角落上的数字,即A11+A14+A41+A44=34。
2.每个角落上的2×2方格中的数字,例如左上角:A11+A12+A21+A22=34。
3.最中间的2×2方格中的数字,即A22+A23+A32+A33=34。
4.每条水平线上四个格子中的数字,即Ai1+Ai2+Ai3+Ai4=34,其中i=1..4。
5.每条垂直线上四个格子中的数字,即A1j+A2j+A3j+A4j=34,其中j=1..4。
6两条对角线上四个格子中的数字,例如左上角到右下角:A11+A22+A33+A44=34。
右上角到左下角:A14+A23+A32+A41=34
【输入】
输入文件会指定把数字1先固定在某一格内。输入的文件只有一行包含两个正数据I和J,表示第1行和第J列的格子放数字1。剩下的十五个格子,请按照前述六项条件用数字2到16来填满。
【输出】
把全部的正确解答用每4行一组写到输出文件,每行四个数,相邻两数之间用一个空格隔开。两组答案之间,要以一个空白行相间,并且依序排好。排序的方式,是先从第一行的数字开始比较,每一行数字,由最左边的数字开始比,数字较小的解答必须先输出到文件中。
【样例】
magic.in
1 1
magic.out
1 4 13 16
14 15 2 3
8 5 12 9
11 10 7 6
1 4 13 16
14 15 2 3
12 9 8 5
7 6 11 10{样例输出没写完}
====================================
初始想法:
开5个hash
判断是否>34
若>34则剪掉...
但是这个想法有一个根本上的问题。
就是若前面的那些小于34的话后面就有很多冗余操作
所以初始想法就是错误的...
---------------------------------------------------------------------
正确做法:
直接搜到关键节点的时候直接判断是否=34
若<>34则剪掉。
-----------------------------------------------------------------------
所以在做这类似的有剪枝的search题的时候
应该先考虑剪枝的正确性。在考虑剪枝如何实现。
===========================================
源程序名 magic.???(pas, c, cpp) 可执行文件名 magic.exe 输入文件名 magic.in 输出文件名 magic.out |
填数字方格的游戏有很多种变化,如下图所示的4×4方格中,我们要选择从数字1到16来填满这十六个格子(Aij,其中i=1..4,j=1..4)。为了让游戏更有挑战性,我们要求下列六项中的每一项所指定的四个格子,其数字累加的和必须为34:
1.四个角落上的数字,即A11+A14+A41+A44=34。
2.每个角落上的2×2方格中的数字,例如左上角:A11+A12+A21+A22=34。
3.最中间的2×2方格中的数字,即A22+A23+A32+A33=34。
4.每条水平线上四个格子中的数字,即Ai1+Ai2+Ai3+Ai4=34,其中i=1..4。
5.每条垂直线上四个格子中的数字,即A1j+A2j+A3j+A4j=34,其中j=1..4。
6两条对角线上四个格子中的数字,例如左上角到右下角:A11+A22+A33+A44=34。
右上角到左下角:A14+A23+A32+A41=34
A11 | A12 | A13 | A14 |
A21 | A22 | A23 | A24 |
A31 | A32 | A33 | A34 |
A41 | A42 | A43 | A44 |
输入文件会指定把数字1先固定在某一格内。输入的文件只有一行包含两个正数据I和J,表示第1行和第J列的格子放数字1。剩下的十五个格子,请按照前述六项条件用数字2到16来填满。
【输出】
把全部的正确解答用每4行一组写到输出文件,每行四个数,相邻两数之间用一个空格隔开。两组答案之间,要以一个空白行相间,并且依序排好。排序的方式,是先从第一行的数字开始比较,每一行数字,由最左边的数字开始比,数字较小的解答必须先输出到文件中。
【样例】
magic.in
1 1
magic.out
1 4 13 16
14 15 2 3
8 5 12 9
11 10 7 6
1 4 13 16
14 15 2 3
12 9 8 5
7 6 11 10{样例输出没写完}
====================================
初始想法:
开5个hash
判断是否>34
若>34则剪掉...
但是这个想法有一个根本上的问题。
就是若前面的那些小于34的话后面就有很多冗余操作
所以初始想法就是错误的...
---------------------------------------------------------------------
正确做法:
直接搜到关键节点的时候直接判断是否=34
若<>34则剪掉。
-----------------------------------------------------------------------
所以在做这类似的有剪枝的search题的时候
应该先考虑剪枝的正确性。在考虑剪枝如何实现。
===========================================
var f:array[2..16]of boolean; //f_bool:array[1..5,0..4]of longint; //z:array[1..16,1..5,0..4]of longint; z:array[1..16]of longint; x,y,v_1:longint; procedure init; begin assign(input,'magic.in'); assign(output,'magic.out'); reset(input); rewrite(output); end; procedure terminate; begin close(input); close(output); halt; end; procedure dfs(t:longint); var i:longint; j:longint; flag:boolean; begin if t>16 then begin for i:=1 to 16 do begin write(z[i],' '); if i mod 4=0 then writeln; end; writeln; exit; end; if t=v_1 then begin flag:=false; if t=4 then if z[1]+z[2]+z[3]+z[4]<>34 then flag:=true; if t=6 then if z[1]+z[2]+z[5]+z[6]<>34 then flag:=true; if t=8 then begin if z[5]+z[6]+z[7]+z[8]<>34 then flag:=true; if z[7]+z[8]+z[3]+z[4]<>34 then flag:=true; end; if t=11 then if z[10]+z[11]+z[6]+z[7]<>34 then flag:=true; if t=13 then begin if z[1]+z[5]+z[9]+z[13]<>34 then flag:=true; if z[4]+z[7]+z[10]+z[13]<>34 then flag:=true; end; if t=14 then begin if z[9]+z[10]+z[11]+z[12]<>34 then flag:=true; if z[2]+z[6]+z[10]+z[14]<>34 then flag:=true; if z[9]+z[10]+z[13]+z[14]<>34 then flag:=true; end; if t=15 then if z[3]+z[7]+z[11]+z[15]<>34 then flag:=true; if t=16 then begin if z[13]+z[14]+z[15]+z[16]<>34 then flag:=true; if z[4]+z[8]+z[12]+z[16]<>34 then flag:=true; if z[1]+z[4]+z[13]+z[16]<>34 then flag:=true; if z[11]+z[12]+z[15]+z[16]<>34 then flag:=true; if z[1]+z[6]+z[11]+z[16]<>34 then flag:=true; end; if not flag then dfs(t+1); exit; end; for i:=2 to 16 do if f[i] then begin f[i]:=false; z[t]:=i; if t=4 then begin if z[1]+z[2]+z[3]+z[4]<>34 then begin f[i]:=true; continue; end; end; if t=6 then begin if z[1]+z[2]+z[5]+z[6]<>34 then begin f[i]:=true; continue; end; end; if t=8 then begin if z[5]+z[6]+z[7]+z[8]<>34 then begin f[i]:=true; continue; end; if z[7]+z[8]+z[3]+z[4]<>34 then begin f[i]:=true; continue; end; end; if t=11 then begin if z[10]+z[11]+z[6]+z[7]<>34 then begin f[i]:=true; continue; end; end; if t=13 then begin if z[1]+z[5]+z[9]+z[13]<>34 then begin f[i]:=true; continue; end; if z[4]+z[7]+z[10]+z[13]<>34 then begin f[i]:=true; continue; end; end; if t=14 then begin if z[9]+z[10]+z[11]+z[12]<>34 then begin f[i]:=true; continue; end; if z[2]+z[6]+z[10]+z[14]<>34 then begin f[i]:=true; continue; end; if z[9]+z[10]+z[13]+z[14]<>34 then begin f[i]:=true; continue; end; end; if t=15 then begin if z[3]+z[7]+z[11]+z[15]<>34 then begin f[i]:=true; continue; end; end; if t=16 then begin if z[13]+z[14]+z[15]+z[16]<>34 then begin f[i]:=true; continue; end; if z[4]+z[8]+z[12]+z[16]<>34 then begin f[i]:=true; continue; end; if z[1]+z[4]+z[13]+z[16]<>34 then begin f[i]:=true; continue; end; if z[11]+z[12]+z[15]+z[16]<>34 then begin f[i]:=true; continue; end; if z[1]+z[6]+z[11]+z[16]<>34 then begin f[i]:=true; continue; end; end; dfs(t+1); f[i]:=true; end; end; procedure main; var i:longint; begin readln(x,y); fillchar(f,sizeof(f),true); v_1:=(x-1)*4+y; z[v_1]:=1; dfs(1); end; begin init; main; terminate; end.
相关文章推荐
- 魔术数字游戏
- 猜数字游戏
- [转贴]玩你没商量:ADSL速率数字游戏解密
- 数字游戏,并且随机生成目标数字版
- 猜数字游戏——初探 python 界面编程
- 《C语言及程序设计》实践项目——数字游戏
- jquery开发的数字相加游戏(你能玩几分)
- 公司新年网页抽奖程序 数字抽奖游戏JS特效
- 数字游戏 2135 (排序)
- 数字游戏(两个大神写得)
- Problem 2089 数字游戏
- java猜数字游戏
- 简单猜数字游戏
- 质数筛 51Nod1441 士兵的数字游戏
- 数字游戏
- 数字游戏
- JS数字抽奖游戏实现方法
- 小游戏——给五名运动员排名、找凶手、模拟银行密码三次输入场景、猜数字游戏,猜大或者猜小直到猜正确
- 算法笔记_179:历届试题 数字游戏(Java)
- 凑数字游戏