Painter's Problem

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5875   Accepted: 2825

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

 

很明显的异或版Gauss 消元,其中还要枚举出自由变元的取值来确定确定变元的值以查找最小的答案。
 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define clr(x) memset(x,0,sizeof(x))
#define clrdown(x) memset(x,-1,sizeof(x))
using namespace std;
int A[][];
int x[];
int free_x[];
int mov[][]={,,,-,,,-,};
char s[];
void init(int n);
int Gauss(int n);
int main()
{
int T,n,p;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init(n);
if((p=Gauss(n))==-)
{
printf("inf\n");
}
else
{
printf("%d\n",p);
} }
return ;
}
//初始化以及读入操作
void init(int n)
{
clr(A);
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
A[i*n+j][i*n+j]=;
for(int k=;k<;k++)
if(i+mov[k][]>= && i+mov[k][]<n && j+mov[k][]>= && j+mov[k][]<n)
{
A[(i+mov[k][])*n+j+mov[k][]][i*n+j]=;
}
}
for(int i=;i<n;i++)
{
scanf("%s",s);
for(int j=;j<n;j++)
if(s[j]=='w')
A[i*n+j][n*n]=;
}
/* for(int i=0;i<n*n;i++)
{
for(int j=0;j<=n*n;j++)
printf("%d ",A[i][j]);
printf("\n");
}*/
clr(free_x);
return ;
}
//gauss消元部分
int Gauss(int n)
{
int num=;
int k,col;
//从第0行0列开始消元
for(k=,col=;k<n*n && col<n*n;col++,k++)
{
if(!A[k][col])
{
for(int i=k+;i<n*n;i++)
if(A[i][col])
{
for(int j=col;j<=n*n;j++)
swap(A[k][j],A[i][j]);
break;
}
}//找k列有最大值的行与之交换(即只要有1)。
if(!A[k][col])
{
k--;
free_x[num++]=col;//记录自由变元的位置
continue;
}//该行全是0,指向当前行下一列并记录自由变元的下标col
for(int i=k+;i<n*n;i++)
if(A[i][col])
for(int j=col;j<=n*n;j++)
A[i][j]=(A[i][j]+A[k][j])%;
}//消元部分
for(int i=;i<n*n;i++)
/* {
for(int j=0;j<=n*n;j++)
printf("%d ",A[i][j]);
printf("\n");
}
printf("%d %d\n",num,k);*/
for(int i=k;i<n*n;i++)
if(A[i][n*n])
return -;
//若k行及之后有(0,0,0,0,……,1)的行则无解,返回-1
int p=n*n-k;//p即为自由变元的数量
int c,temp,ans,minn=,index,ct;
for( index=;index<(<<p);index++)//index从0开始枚举自由变元至1<<p
{
clrdown(x);
ans=;
ct=index;
for(int i=;i<p;ct>>=,i++)
if(ct&)
{
ans++;
x[free_x[i]]=;
}
else
x[free_x[i]]=;
//给是自由变元的x[i]赋值
for(int i=k-;i>=;i--)
{
c=n*n-;
temp=A[i][col];
while(x[c]!=-)
{
if(x[c])
temp=(temp+A[i][c])%;
c--;
}
x[c]=temp;
if(x[c])
ans++;
}
if(ans<minn)
minn=ans;
// printf("%d %d\n",minn,ans);
}
return minn;
}
 
 
 
 

poj 1681(Gauss 消元)的更多相关文章

  1. POJ 1681 高斯消元 枚举自由变元

    题目和poj1222差不多,但是解法有一定区别,1222只要求出任意一解,而本题需要求出最少翻转次数.所以需要枚举自由变元,变元数量为n,则枚举的次数为1<<n次 #include < ...

  2. POJ 1830 开关问题(Gauss 消元)

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

  3. hdu 5755(Gauss 消元) &poj 2947

    Gambler Bo Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tota ...

  4. $Gauss$消元

    $Gauss$消元 今天金牌爷来问我一个高消的题目,我才想起来忘了学高消... 高斯消元用于解线性方程组,也就是形如: $\left\{\begin{matrix}a_{11}x_1+a_{12}x_ ...

  5. 求一个n元一次方程的解,Gauss消元

    求一个n元一次方程的解,Gauss消元 const Matrix=require('./Matrix.js') /*Gauss 消元 传入一个矩阵,传出结果 */ function Gauss(mat ...

  6. Gauss 消元(模板)

    /* title:Gauss消元整数解/小数解整数矩阵模板 author:lhk time: 2016.9.11 没学vim的菜鸡自己手打了 */ #include<cstdio> #in ...

  7. POJ 1222 POJ 1830 POJ 1681 POJ 1753 POJ 3185 高斯消元求解一类开关问题

    http://poj.org/problem?id=1222 http://poj.org/problem?id=1830 http://poj.org/problem?id=1681 http:// ...

  8. poj 2065 高斯消元(取模的方程组)

    SETI Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1735   Accepted: 1085 Description ...

  9. POJ1830开关问题——gauss消元

    题目链接 分析: 第一个高斯消元题目,操作是异或.奇偶能够用0.1来表示,也就表示成bool类型的方程,操作是异或.和加法没有差别 题目中有两个未知量:每一个开关被按下的次数(0.1).每一个开关的转 ...

随机推荐

  1. JS练习题(左侧菜单下拉+好友选中)

    题一.左侧菜单下拉 做题思路:先做菜单和子菜单,把子菜单默认隐藏.再用JS调样式. <style type="text/css"> *{ margin:0px auto ...

  2. performSelector支持多参数

    默认的performSelector支持最多传递两个参数,要想传递超过两个的参数,需要使用NSInvocation来模拟performSelector的行为,如下: - (id)performSele ...

  3. 【转载】Lua脚本语法说明(修订)

    原文:http://www.cnblogs.com/ly4cn/archive/2006/08/04/467550.html 挑出来几个 .逻辑运算 and, or, not 其中,and 和 or ...

  4. 01背包问题的延伸即变形 (dp)

    对于普通的01背包问题,如果修改限制条件的大小,让数据范围比较大的话,比如相比较重量而言,价值的范围比较小,我们可以试着修改dp的对象,之前的dp针对不同的重量限制计算最大的价值.这次用dp针对不同的 ...

  5. python3中字典的遍历和合并

    #字典的遍历方式 dic={"a":1,"b":2,"c":3} for k in dic: print (k,dic[k]) for k, ...

  6. vim 以16进制进行文件编辑

    用 vim中二进制文件的编辑是先通过外部程序xxd来把文件dump成其二进制的文本形式,然后就可以按通常的编辑方式对文件进行编辑,编辑完成后再用xxd 转化为原来的形式即可. 可分如下几步进行: (1 ...

  7. Python模块学习 - Argparse

    argparse模块 在Python中,argparse模块是标准库中用来解析命令行参数的模块,用来替代已经过时的optparse模块.argparse模块能够根据程序中的定义从sys.argv中解析 ...

  8. python实战===itchat

    import itchat itchat.login() friends=itchat.get_friends(update=True)[0:] male=female=other=0 for i i ...

  9. 64_j1

    JSCookMenu-2.0.4-13.fc26.noarch.rpm 13-Feb-2017 22:06 38098 Java-WebSocket-1.3.1-0.2.git58d1778.fc24 ...

  10. pandas+sqlalchemy 保存数据到mysql

    import pandas as pd from sqlalchemy import create_engine data3={"lsit1":[1,2],"lsit2& ...