版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/happy_Du/article/details/75103668
题目链接: 点我
题目大意: 一个5*6的网格,每次反转一个方格及相邻的四个,要把所有的反转成0
题目分析: 暴力枚举第一行的所有反转方案,然后就可以确定剩下4行的方案了。据说用高斯消元也可以,但是蒟蒻的我并不会。(省选的时候就是这题。。。当时用贪心做的,每次只考虑2*2的方格,水了30分。。。)
PS:测试输出没有删干净。。。初始化也没弄清楚,导致全是0的点过不去。。。WA了半多小时
Problem: 1222 User: ChenyangDu
Memory: 156K Time: 0MS
Language: C++ Result: Accepted
Source Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 0x7fffffff,map[2][5] = {1,0,0,-1,0,0,1,-1,0,0};
int in[10][10],ans[10][10],out[10][10];//ans是中间变量,out是最终结果
int get_color(int x,int y){
int color = in[x][y];
for(int i=0;i<5;i++){
int a = x + map[0][i],
b = y + map[1][i];
if(a>=0 && a<5 && b>=0 && b<6 && ans[a][b] == 1){
color ++;
}
}
return color % 2;
}
int cal(){
int res = 0;
for(int i=1;i<5;i++){
for(int j=0;j<6;j++){
if(get_color(i-1,j) == 1){
ans[i][j] = 1;
res++;
}
}
}
for(int i=0;i<6;i++){
if(get_color(4,i))return -1;
}
return res;
}
int main(){
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
int t = 0;
while(t++<T){
memset(out,0,sizeof(out));
for(int i=0;i<5;i++){
for(int j=0;j<6;j++){
scanf("%d",&in[i][j]);
}
}
memset(ans,0,sizeof(ans));
for(int i=0;i<(1<<7);i++){//暴力枚举第一行
memset(ans,0,sizeof(ans));
for(int j=0;j<6;j++){
ans[0][6-j-1] = (i>>j)&1;
}
if(cal()>0){
memcpy(out,ans,sizeof(out));
break;
}
}
printf("PUZZLE #%d\n",t);
for(int i=0;i<5;i++){
for(int j=0;j<5;j++)
printf("%d ",out[i][j]);
printf("%d\n",out[i][5]);
}
}
fclose(stdin);
return 0;
}