解谜类游戏的不正确玩法(用⑨重for循环玩密室献祭)(顺便求正解)

来源:互联网 发布:温湿度数据采集器 编辑:程序博客网 时间:2024/05/18 00:16

 玩解谜类游戏智商不够怎么办?我可以问问神(电)奇(脑)海(编)螺(程)啊...
于是,九层for循坏暴力搜索再现江湖...
来源:密室献祭-杂草 
关卡描述:  把9个方块放在格子里,使每个方块相邻的颜色相同
 下图是空格子

图片

下图是备选方块
图片
下图是摆放方法示例
图片

我先试着能不能直接枚举,但随后发现可能情况太多,靠人力枚举不现实。
那怎么办呢?只好靠电脑枚举了。

解法1:⑨重for循环

尝试用编程解决,发现图中一共就9个格子和9个方块,对计算机而言枚举数相当少...
于是,干脆直接用for循环暴力枚举9个位置上可能放入的方块

首先给每个方块编码(见第二张图,从最右边的方块起逆时针给方块编号为1-9)
函数如下

void pra()
{
kuai[1].u='b';kuai[1].d='y';kuai[1].r='g';kuai[1].l='r';//字母代表颜色,u->up,d->down,r->right,l->left
kuai[2].u='b';kuai[2].d='r';kuai[2].r='y';kuai[2].l='g';
kuai[3].u='y';kuai[3].d='b';kuai[3].r='r';kuai[3].l='g';
kuai[4].u='y';kuai[4].d='g';kuai[4].r='r';kuai[4].l='b';
kuai[5].u='b';kuai[5].d='r';kuai[5].r='g';kuai[5].l='y';
kuai[6].u='g';kuai[6].d='r';kuai[6].r='b';kuai[6].l='y';
kuai[7].u='g';kuai[7].d='b';kuai[7].r='y';kuai[7].l='r';
kuai[8].u='r';kuai[8].d='b';kuai[8].r='y';kuai[8].l='g';
kuai[9].u='b';kuai[9].d='g';kuai[9].r='r';kuai[9].l='y';
}
 
之后是9重for循环

void deal()
{
int t[15];
for(t[1]=1;t[1]<=9;t[1]++)
if(kuai[t[1]].u=='b')
{
tu[t[1]]=true;
for(t[2]=1;t[2]<=9;t[2]++)
if(!tu[t[2]]&&kuai[t[2]].l==kuai[t[1]].r)
{
tu[t[2]]=true;
for(t[3]=1;t[3]<=9;t[3]++)
if(!tu[t[3]]&&kuai[t[3]].l==kuai[t[2]].r)
{
tu[t[3]]=true;
for(t[4]=1;t[4]<=9;t[4]++)
if(!tu[t[4]]&&kuai[t[4]].u==kuai[t[1]].d)
{
tu[t[4]]=true;
for(t[5]=1;t[5]<=9;t[5]++)
if(!tu[t[5]]&&kuai[t[5]].u==kuai[t[2]].d&&kuai[t[5]].l==kuai[t[4]].r)
{
tu[t[5]]=true;
for(t[6]=1;t[6]<=9;t[6]++)
if(!tu[t[6]]&&kuai[t[6]].u==kuai[t[3]].d&&kuai[t[6]].l==kuai[t[5]].r)
{
tu[t[6]]=true;
for(t[7]=1;t[7]<=9;t[7]++)
if(!tu[t[7]]&&kuai[t[7]].u==kuai[t[4]].d)
{
tu[t[7]]=true;
for(t[8]=1;t[8]<=9;t[8]++)
if(!tu[t[8]]&&kuai[t[8]].u==kuai[t[5]].d&&kuai[t[8]].l==kuai[t[7]].r)
{
tu[t[8]]=true;
for(t[9]=1;t[9]<=9;t[9]++)
if(!tu[t[9]]&&kuai[t[9]].u==kuai[t[6]].d&&kuai[t[9]].l==kuai[t[8]].r&&kuai[t[9]].r=='r')
{
for(int i=1;i<=9;i++)
printf("%d",t[i]);
putchar('\n');
}
tu[t[8]]=false;
}
tu[t[7]]=false;
}
tu[t[6]]=false;
}
tu[t[5]]=false;
}
tu[t[4]]=false;
}
tu[t[3]]=false;
}
tu[t[2]]=false;
}
tu[t[1]]=false;
}
}
代码宽度喜闻乐见

以下是c++代码的其他部分

#include<cstdio>
struct node{char u,d,r,l;}kuai[15];
int tu[15];
int main()
{
pra();
deal();
}

编译,运行,得到结果。输出是从第一到第九个格子应放的方块编号。
 图片

速度很快
按程序输出的结果把方块放入格子里

图片

完成了

解法二:由于⑨重for循环实在太过蛋疼,于是我考虑用递归减小代码量
两种算法思想是一致的,但输出不同,递归的方法输出的是从1到9每一个方块应放在格子中的位置
虽然递归方法的代码缩短了,扩展性变强了,但时耗增加了。

void deal2(int loca,int tu[])
{
int up=10,left=10;
for(int i=1;i<=9;i++)
{
if(tu[i]==loca-3&&loca>3) up=i;
if(tu[i]==loca-1&&(loca%3)!=1) left=i;
}
for(int i=1;i<=9;i++)
if(!tu[i])
{
if(loca==9)
{
if(kuai[i].l==kuai[left].r&&kuai[i].u==kuai[up].d)
{
tu[i]=loca;
ansnum++;
for(int j=1;j<=9;j++)
ans[ansnum][j]=tu[j];
}
return ;
}
if(loca==1&&kuai[i].u=='b')
{
tu[i]=loca;
deal2(loca+1,tu);
tu[i]=0;
}
if(((loca<=3)||(kuai[i].u==kuai[up].d))&&((loca%3==1)||(kuai[i].l==kuai[left].r)))
{
tu[i]=loca;
deal2(loca+1,tu);
tu[i]=0;
}
}
}
void output()
{
for(int i=1;i<=ansnum;i++)
{
for(int j=1;j<=9;j++)
printf("%d",ans[i][j]);
putchar('\n');
}
}

于是电脑补足了我大脑的智商,让我通过了这关...

ps:求其他更机智的解法
应该会有更聪明的搜索方法,请各位大神指点...
同时,既然是设计给人脑的游戏,那就应该有通过纸和笔就能解决的方法,请各位大神指点...
 
附件:两份代码 
http://pan.baidu.com/s/1jIK0XKE
http://pan.baidu.com/s/1jI6TMrs 

0 0
原创粉丝点击