任意门:http://poj.org/problem?id=1681

Painter's Problem
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 7667   Accepted: 3624

Description

There is a square wall which is made of n*n small square bricks. Some bricks are white while some bricks are yellow. Bob is a painter and he wants to paint all the bricks yellow. But there is something wrong with Bob's brush. Once he uses this brush to paint brick (i, j), the bricks at (i, j), (i-1, j), (i+1, j), (i, j-1) and (i, j+1) all change their color. Your task is to find the minimum number of bricks Bob should paint in order to make all the bricks yellow. 

Input

The first line contains a single integer t (1 <= t <= 20) that indicates the number of test cases. Then follow the t cases. Each test case begins with a line contains an integer n (1 <= n <= 15), representing the size of wall. The next n lines represent the original wall. Each line contains n characters. The j-th character of the i-th line figures out the color of brick at position (i, j). We use a 'w' to express a white brick while a 'y' to express a yellow brick.

Output

For each case, output a line contains the minimum number of bricks Bob should paint. If Bob can't paint all the bricks yellow, print 'inf'.

Sample Input

2
3
yyy
yyy
yyy
5
wwwww
wwwww
wwwww
wwwww
wwwww

Sample Output

0
15

Source

题意概括:

一个二维矩阵, 输入每个格子的初始颜色,可以进行的操作是 粉刷一个格子则相邻的上下左右四个各自颜色都会取反(只有两种颜色);

问最后把全部各自涂成黄色的最小操作数;

解题思路:

根据题意,每个各自都是一个变元,根据各自之间的相邻关系构造增广矩阵;

高斯消元求出自由元个数 sum;

二进制枚举方案,找出最小的操作数;

AC code:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = ; int equ, var;
int a[MAXN][MAXN];
char str[MAXN][MAXN];
int x[MAXN];
int free_x[MAXN];
int free_num;
int N; int Gauss()
{
int maxRow, col, k;
free_num = ;
for(k = , col = ; k < equ && col < var; k++, col++){
maxRow = k;
for(int i = k+; i <equ; i++){
if(abs(a[i][col]) > abs(a[maxRow][col]))
maxRow = i;
}
if(a[maxRow][col] == ){ //最大的都为0说明该列下面全是 0
k--;
free_x[free_num++] = col; //说明col是自由元
continue;
}
if(maxRow != k){ //交换行
for(int j = col; j < var+; j++)
swap(a[k][j], a[maxRow][j]);
}
for(int i = k+; i < equ; i++){ //消元
if(a[i][col] != ){
for(int j = col; j < var+; j++){
a[i][j] ^= a[k][j];
}
}
}
}
for(int i = k; i< equ; i++){
if(a[i][col] != ) return -; //无解
}
if(k < var) return var-k; //返回自由元个数 for(int i = var-; i >= ; i--){ //唯一解,回代
x[i] = a[i][var];
for(int j = i+; j < var; j++){
x[i] ^= (a[i][j] && x[j]);
}
}
return ;
} void init()
{
memset(a, , sizeof(a));
memset(x, , sizeof(x));
equ = N*N;
var = N*N;
for(int i = ; i < N; i++){ //构造增广矩阵
for(int j = -; j < N; j++){
int t = i*N+j;
a[t][t] = ;
if(i > ) a[(i-)*N+j][t] = ;
if(i < N-) a[(i+)*N+j][t] = ;
if(j > ) a[i*N+j-][t] = ;
if(j < N-) a[i*N+j+][t] = ;
}
}
} void solve()
{
int t = Gauss();
if(t == -){ //无解
printf("inf\n");
return;
}
else if(t == ){ //唯一解
int ans = ;
for(int i = ; i < N*N; i++){
ans += x[i];
}
printf("%d\n", ans);
return;
}
else{ //多解,需要枚举自由元
int ans = INF;
int tot = <<t;
int cnt = ;
for(int i = ; i < tot; i++){
cnt = ;
for(int j = ; j < t; j++){
if(i&(<<j)){
x[free_x[j]] = ;
cnt++;
}
else x[free_x[j]] = ;
} for(int j = var-t-; j >= ; j--){
int index;
for(index = j; index < var; index++){
if(a[j][index]) break;
}
x[index] = a[j][var]; for(int s = index+; s < var; s++)
if(a[j][s]) x[index] ^= x[s]; cnt+=x[index];
}
ans = min(ans, cnt);
}
printf("%d\n", ans);
}
} int main()
{
int T_case;
int tpx, tpy;
scanf("%d", &T_case);
while(T_case--){
scanf("%d", &N);
init();
for(int i = ; i < N; i++){
scanf("%s", str[i]);
for(int j = ; j < N; j++){
tpx = i*N+j, tpy = N*N;
if(str[i][j] == 'y') a[tpx][tpy] = ;
else a[tpx][tpy] = ;
}
}
solve();
}
return ;
}

POJ 1681 Painter's Problem 【高斯消元 二进制枚举】的更多相关文章

  1. POJ 1681 Painter's Problem (高斯消元)

    题目链接 题意:有一面墙每个格子有黄白两种颜色,刷墙每次刷一格会将上下左右中五个格子变色,求最少的刷方法使得所有的格子都变成yellow. 题解:通过打表我们可以得知4*4的一共有4个自由变元,那么我 ...

  2. POJ 1681 Painter's Problem [高斯消元XOR]

    同上题 需要判断无解 需要求最小按几次,正确做法是枚举自由元的所有取值来遍历变量的所有取值取合法的最小值,然而听说数据太弱自由元全0就可以就水过去吧.... #include <iostream ...

  3. POJ 1222【异或高斯消元|二进制状态枚举】

    题目链接:[http://poj.org/problem?id=1222] 题意:Light Out,给出一个5 * 6的0,1矩阵,0表示灯熄灭,反之为灯亮.输出一种方案,使得所有的等都被熄灭. 题 ...

  4. POJ 1681 Painter's Problem(高斯消元+枚举自由变元)

    http://poj.org/problem?id=1681 题意:有一块只有黄白颜色的n*n的板子,每次刷一块格子时,上下左右都会改变颜色,求最少刷几次可以使得全部变成黄色. 思路: 这道题目也就是 ...

  5. poj 1681 Painter&#39;s Problem(高斯消元)

    id=1681">http://poj.org/problem? id=1681 求最少经过的步数使得输入的矩阵全变为y. 思路:高斯消元求出自由变元.然后枚举自由变元,求出最优值. ...

  6. poj 1681 Painter's Problem

    Painter's Problem 题意:给一个n*n(1 <= n <= 15)具有初始颜色(颜色只有yellow&white两种,即01矩阵)的square染色,每次对一个方格 ...

  7. POJ 2947 Widget Factory(高斯消元)

    Description The widget factory produces several different kinds of widgets. Each widget is carefully ...

  8. POJ 1830 开关问题(高斯消元)题解

    思路:乍一看好像和线性代数没什么关系.我们用一个数组B表示第i个位置的灯变了没有,然后假设我用u[i] = 1表示动开关i,mp[i][j] = 1表示动了i之后j也会跟着动,那么第i个开关的最终状态 ...

  9. POJ 1830 开关问题(高斯消元求解的情况)

    开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 8714   Accepted: 3424 Description ...

随机推荐

  1. spark第十八篇:Tuning Spark 调优

    由于大多数Spark应用都是在内存中计算的,所以,Spark程序的瓶颈可能是集群中的任何资源,比如CPU,网络带宽或者内存等.本指南主要涵盖两个主题: 1.数据序列化.这对于良好的网络性能至关重要,还 ...

  2. git 拉新项目

                   

  3. Unity GetComponentsInChildren<T>(true);

    using System.Collections; using System.Collections.Generic; using UnityEngine; public class GetCompo ...

  4. Java基础25-静态代码块

    /* 静态代码块 格式: static{ 静态代码块中执行语句 } 特点:随着类的加载而执行,并且只会执行一次,并且还优先于主函数. 作用:用于给类进行初始化 */ public class Test ...

  5. (转)Shell中read的用法详解

    Shell中read的用法详解 原文:http://blog.csdn.net/jerry_1126/article/details/77406500 read的常用用法如下: read -[pstn ...

  6. 06-struts2与ognl的结合

    1 参数接收 2 配置文件中 1 Demo2Action package www.test.c_config; import com.opensymphony.xwork2.ActionSupport ...

  7. pat09-散列3. Hashing - Hard Version (30)

    09-散列3. Hashing - Hard Version (30) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 HE, Qin ...

  8. pat1007. Maximum Subsequence Sum (25)

    1007. Maximum Subsequence Sum (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...

  9. 【VMware】安装不同系统的虚拟机出现开机黑屏的情况

    解决方法一: 1.以管理员身份运行命令提示符(cmd.exe),输入命令 netsh winsock show catalog 按下回车键执行命令(可以看到VMware注册了两个LSP:vSocket ...

  10. 如何优化VMWare虚拟机的运行速度(转)

    虚拟机是个好东西,但是对电脑有一定的要求.尤其对做工控的来说都需要安装一些大型的软件(其中WINCC最难装,对系统要求较高.而且像WIN 7 64位的就别想装上去了,如果改系统后那4G以上的内存不就浪 ...