描述
游戏“The Pilots Brothers:跟随有条纹的大象”有一个玩家需要打开冰箱的任务。
冰箱门上有16个把手。每个手柄可以处于以下两种状态之一:打开或关闭。只有当所有把手都打开时,冰箱才会打开。手柄表示为矩阵4х4。您可以在任何位置[i,j](1≤i,j≤4)更改句柄的状态。但是,这也会更改第i行中所有句柄和第j列中所有句柄的状态。
任务是确定打开冰箱所需的最小手柄切换次数。
输入
输入包含四行。四行中的每一行包含四个描述适当句柄的初始状态的字符。符号“+”表示手柄处于闭合状态,而符号“ - ”表示“打开”。至少一个手柄最初是关闭的。
产量
输入的第一行包含N - 最小切换次数。其余N行描述切换顺序。每行包含由一个或多个空格分隔的矩阵的行号和列号。如果有多种解决方案,您可以提供其中任何一种解决方案。
Sample Input
-+-- ---- ---- -+--
Sample Output
6 1 1 1 3 1 4 4 1 4 3 4 4
遍历问题,我用的是dfs,用深搜实现每次记忆化的搜索,设个结果栈,设个过程栈,
更新最少次数的时候更新结果栈的结果。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int a[4][4];
stack<int> sta;
stack<int> ans;
int Min=0x7fffffff;
int check()//检查
{
int i,j;
for(i=0; i<4; ++i)
for(j=0; j<4; ++j)
if(a[i][j]!=0)
return -1;
return 1;
}
void change(int x,int y){
for(int i=0;i<4;i++){
a[x][i]=!a[x][i];
}
for(int i=0;i<4;i++){
if(i!=x) //千万别翻两遍
a[i][y]=!a[i][y];
}
}
void dfs(int d,int step)
{
int x,y;
if(d==16){
if(check()==1)
if(step<Min){
Min=step;
ans=sta;
}
return;
}else{
x=d/4;
y=d%4;
dfs(d+1,step);
change(x,y);
sta.push(d);
dfs(d+1,step+1);
sta.pop();
change(x,y);
}
}
int main()
{
char t;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
cin>>t;
if(t=='+') a[i][j]=1;
else a[i][j]=0;
}
}
dfs(0,0);
if(Min==0x7fffffff)
cout<<"Impossible"<<endl;
else
cout<<Min<<endl;
if(ans.empty()){
cout<<"empty"<<endl;
}
int x,y,z;
while(!ans.empty())
{
z=ans.top();
ans.pop();
x=z/4;
y=z%4;
cout<<x+1<<" "<<y+1<<endl;
}
return 0;
}
本文探讨了游戏“ThePilotsBrothers:跟随有条纹的大象”中一个有趣的数学挑战——如何使用最少的操作次数打开一扇带有16个开关的冰箱门。通过深度优先搜索算法,我们找到了解决问题的有效方法,并分享了解题思路和C++代码实现。
1372

被折叠的 条评论
为什么被折叠?



