文章目录
- 1. 题目
- 1.1 题目链接
- 1.2 题目大意
- 1.3 解题思路
- 2. 代码
- 2.1 Accepted代码
1. 题目
1.1 题目链接
http://poj.org/problem?id=2965
1.2 题目大意
有一个4*4的符号矩阵(+和-),改变一个元素的符号,它所在的行和列的其他元素也改变符号,求最少次数使得所有的符号变成 - 号,并顺序打印出操作符号的位置。
1.3 解题思路
采用回溯算法,暴力枚举
2. 代码
2.1 Accepted代码
/*** @description: 回溯算法求解* @author: michael ming* @date: 2019/7/12 23:08* @modified by: */
#include <iostream>
#include <string>
#include <queue>
using namespace std;
bool a[4][4];//存储地图
struct position//位置
{int row;int column;
};
position posi[30];//位置信息
position finalposi[30];//成功开门的位置信息
bool isok()//判断是否都是-号(0)
{int i, j;for(i = 0; i < 4; ++i){for(j = 0; j < 4; ++j){if(a[i][j] != 0){return false;}}}return true;
}
void flipAndUpdate(int r, int c)//翻转r,c处及其所在行和列
{a[r][c] = !a[r][c];for(int i = 0; i < 4; ++i){a[r][i] = !a[r][i];a[i][c] = !a[i][c];}
}
void flip(int r, int c,int curstep, long &minstep)
{if(isok()){if(curstep < minstep){minstep = curstep;//是一个较短路径for(int i = 0; i < curstep; ++i){//较短路径付给最终要输出的路径数组finalposi[i].row = posi[i].row;finalposi[i].column = posi[i].column;}}return;}if(r == 4)return;if(c+1 < 4)//不按这个按钮flip(r,c+1,curstep,minstep);else if(c+1 == 4)flip(r+1,0,curstep,minstep);flipAndUpdate(r,c);//按这个按钮posi[curstep].row = r;posi[curstep].column = c;//记录按钮位置curstep++;if(c+1 < 4)//按这个按钮flip(r,c+1,curstep,minstep);else if(c+1 == 4)flip(r+1,0,curstep,minstep);flipAndUpdate(r,c);//按完了,还要复原
}
int main()
{string s;int i, j;long minstep = 65536;for(i = 0; i < 4; ++i){cin >> s;for(j = 0; j < 4; ++j){if(s[j] == '-')a[i][j] = 0;elsea[i][j] = 1;}}flip(0,0,0,minstep);cout << minstep << endl;//输出最短次数for(int i = 0; i < minstep; ++i){//输出按按钮的位置信息cout << finalposi[i].row+1 << " " << finalposi[i].column+1 << endl;}return 0;
}