本题知识点:深度优先搜索 + 暴力枚举 + 回溯 + 栈
如果对以上知识点还不熟悉的同学建议先做做 POJ1753 (本题是1753的提高版)(附 POJ1753博客)
以下默认您已ACPOJ1753
相信AC了Flip Game 这题的你,一看到这题就很自然地想到套 Filp Game 的模板。没错,其实几乎是一模一样的。只是存储数据有了一些不同而已。熟悉栈的话你也很自然想到用栈啦。
这里也是“翻棋”,只不过翻的不只是上下左右了,是要翻一整行列,所以这里要修改一下。
情况也还是分翻与不翻,同样需要回溯。
所以很快就可以AC了。不料我写的时候粗心大意没有把 ‘+’ 翻成 ‘-’ ,单这个小错误耽搁了很长的debug时间quq,大家要细心点呀
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
struct node{
int row, column;
}temp[100];
stack<node> ans, cnt;
char bri[10][10];
void init(){
while(!cnt.empty()) cnt.pop();
node a;
a.row = 1; a.column = 1;
for(int i = 0; i < 100; i++) ans.push(a);
}
bool check(){
for(int i = 0; i < 4; i++){
for(int j = 0; j < 4; j++){
if(bri[i][j] != '-') return false;
}
}
return true;
}
void show(){
for(int i = 0; i < 4; i++){
printf("%s
", bri[i]);
} putchar('
');
getchar();
}
void turn(int h, int w){
// row
for(int i = 0; i < 4; i++){
if(bri[h][i] == '+') bri[h][i] = '-';
else bri[h][i] = '+';
}
// column
for(int i = 0; i < 4; i++){
if(i == h) continue;
if(bri[i][w] == '+') bri[i][w] = '-';
else bri[i][w] = '+';
}
}
void dfs(int h, int w){
if(check()){
if(ans.size() > cnt.size()){
while(!ans.empty()) ans.pop();
int len = cnt.size();
for(int i = 0; i < len; i++){
temp[i] = cnt.top();
cnt.pop();
}
for(int i = len - 1; i >= 0; i--){
ans.push(temp[i]);
cnt.push(temp[i]);
}
}
}
if(h == 4) return ;
// change
turn(h, w);
node a;
a.row = h + 1; a.column = w + 1;
cnt.push(a);
if(w == 3) dfs(h + 1, 0);
else dfs(h, w + 1);
turn(h, w);
cnt.pop();
if(w == 3) dfs(h + 1, 0);
else dfs(h, w + 1);
}
int main()
{
init(); // 初始化
for(int i = 0; i < 4; i++) scanf("%s", bri[i]);
dfs(0, 0);
printf("%d
", ans.size());
while(!ans.empty()){
node go = ans.top(); ans.pop();
printf("%d %d
", go.row, go.column);
}
return 0;
}