欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

POJ 1681 Painter's Problem(高斯消元)(异或)

程序员文章站 2024-03-18 16:43:52
...

传送门

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.
POJ 1681 Painter's Problem(高斯消元)(异或)

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

首先这道题就是让你改变一个方块的颜色,但是改变的同时会将上下左右的方块一起改变颜色,然后让你找一个翻块的最小值使所有方块都变成黄色。
由于只有两个颜色,于是我们用0和1来表示。这样就可以直接用异或高斯消元的板子了。

AC代码如下:
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long int LL;
const int MAXL(300);
int a[MAXL+50][MAXL+50];//增广矩阵
int x[MAXL+50];//解集
bool free_x[MAXL];//标记是否是不确定的变元
 
inline int Gauss(int equ,int var)
{
    memset(x,0,sizeof x);
    int maxr,col;
    int k;
    for(k=0,col=0; k<equ&&col<var; k++,col++)
    {
        maxr=k;
        for(int i=k+1; i<equ; i++)
            if(abs(a[i][col])>abs(a[maxr][col]))
                maxr=i;
        if(maxr!=k)
            for(int j=k; j<var+1; j++)	swap(a[k][j],a[maxr][j]);
        if(!a[k][col])
        {
            k--;
            continue;
        }
        for(int i=k+1; i<equ; i++)
        {
            if(a[i][col])
            {
                for(int j=col; j<var+1; j++)
                    a[i][j]^=a[k][j];
            }
        }
    }
    for(int i=k;i<equ;i++){
    	if(a[i][var])return -1;
	}
    for(int i=var-1; i>=0; i--)
    {
        x[i]=a[i][var];
        for(int j=i+1; j<var; j++)
            x[i]^=(a[i][j]&&x[j]);
    }
    return 0;
}
int main()
{
    int T,CASE=1,n;
    char str;
    cin>>T;
    while(T--)
    {
    	cin>>n;
        memset(a,0,sizeof a);
        for(int i=0; i<n*n; i++){
        	cin>>str;
        	if(str=='y')a[i][n*n]=0; 
        	else a[i][n*n]=1;
		}
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                int k=i*n+j;
                a[k][k]=1;
                if(i>0)
                    a[(i-1)*n+j][k]=1;
                if(i<n-1)
                    a[(i+1)*n+j][k]=1;
                if(j>0)
                    a[i*n+j-1][k]=1;  
                if(j<n-1)
                    a[i*n+j+1][k]=1;  
            }
        }
        int ans=Gauss(n*n,n*n);
        if(ans==-1){
        	cout<<"inf"<<endl;
        	continue;
		}
		int sum=0;
        for(int i=0; i<n; i++)
        {
            int temp=i*n;
            if(x[temp]==1)sum++;
            for(int j=1; j<n; j++)
            {
                temp=i*n+j;
                if(x[temp]==1)sum++;
            }
        }
        cout<<sum<<endl;
    }
}