Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 26183 | Accepted: 10089 | Special Judge |
Description
The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.
There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.
The task is to determine the minimum number of handle switching necessary to open the refrigerator.
Input
The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.
Output
The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.
Sample Input
-+-- ---- ---- -+--
Sample Output
6 1 1 1 3 1 4 4 1 4 3 4 4
题意:给出4*4的矩阵,每个位置要么+,要么-,要求经过一种操作,如对第【i,j】个进行操作,则是对第i行和第j列的所有位置都进行变换操作,+变成-,-变成+。经过操作,问最少几步能让矩阵都变成-,且给出步骤。
思路:采取DFS+枚举的思路,对每个位置进行操作或不操作两种情况进行遍历,并用临时数组存储路径,当这种情况符合要求且比现有步骤少的话,就把临时路径赋值给最终的完成路径。这里有个小技巧,用0和1来代表+和-,在操作时可以直接用!来实现操作,即 (!0 == 1)。
代码如下:
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
char mp[5][5];
int map[5][5];
int tempx[20];//临时路径x
int tempy[20];//临时路径y
int stepx[20];//完成的路径x
int stepy[20];//完成的路径y
int step = 0x3f3f3f3f;
int check(){//检查是否可行
int i, j;
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(map[i][j] == 0)return 0;
}
}
return 1;
}
void function(int x, int y){//对x,y坐标的进行操作
map[x][y] = !map[x][y];//注意不要漏掉了单独对该坐标的操作
for(int i = 0; i < 4; i++){
map[i][y] = !map[i][y];
map[x][i] = !map[x][i];
}
}
void dfs(int m, int cnt){//m为第几个位置,cnt为操作的次数
if(check()){//如果符合条件
if(cnt < step){//如果有更少的步骤能够完成
step = cnt;
for(int i = 0; i < step; i++){//将临时路径赋值给完成路径
stepx[i] = tempx[i];
stepy[i] = tempy[i];
}
}
return;
}
if(m > 15)return;
int x = m / 4;
int y = m % 4;
dfs(m + 1, cnt);//如果对该位置不操作,继续遍历
function(x, y);//进行开关操作
tempx[cnt] = x;//给临时路径赋值
tempy[cnt] = y;
dfs(m + 1, cnt + 1);//操作的情况下遍历
function(x, y);
return;
}
int main(){
int n, i, j, x;
for(i = 0; i < 4; i++){
scanf("%s", mp[i]);
}
for(i = 0; i < 4; i++){
for(j = 0; j < 4; j++){
if(mp[i][j] == '+'){
map[i][j] = 0;
}
else{
map[i][j] = 1;
}
}
}
dfs(0, 0);
cout<<step<<endl;
for(i = 0; i < step; i++){
cout<<stepx[i] + 1<<" "<<stepy[i] + 1<<endl;
}
return 0;
}