poj1681--Painter's Problem(高斯消元问题4)

Painter‘s Problem

Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d
& %I64u

Submit Status

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

题目和http://blog.csdn.net/winddreams/article/details/43152305黑白棋完全一样,只是加了n的大小和多组

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define INF 0x3f3f3f3f
int Map[400][400] , a[400] , freex[400] , x[400] ;
char str[20][20] ;
void init(int n)
{
    int i , j , k ;
    memset(Map,0,sizeof(Map)) ;
    for(i = 0 ; i < n ; i++)
    {
        for(j = 0 ; j < n ; j++)
        {
            a[i*n+j] = str[i][j] - '0' ;
            Map[i*n+j][i*n+j] = 1 ;
            if( i > 0 ) Map[i*n+j][i*n+j-n] = 1 ;
            if( i < n-1 ) Map[i*n+j][i*n+j+n] = 1 ;
            if( j > 0 ) Map[i*n+j][i*n+j-1] = 1 ;
            if( j < n-1 ) Map[i*n+j][i*n+j+1] = 1 ;
        }
    }
    return ;
}
void swap1(int p,int q,int n)
{
    int i , temp ;
    temp = a[p] ;
    a[p] = a[q] ;
    a[q] = temp ;
    for(i = 0 ; i < n ; i++)
    {
        temp = Map[p][i] ;
        Map[p][i] = Map[q][i] ;
        Map[q][i] = temp ;
    }
    return ;
}
int solve(int n)
{
    int i , j , k , t = 0 , num1 = 0 ;
    for(i = 0 ; i < n && t < n ; i++ , t++)
    {
        for(j = i ; j < n ; j++)
            if( Map[j][t] ) break ;
        if( j == n )
        {
            i-- ;
            freex[num1++] = t ;
            continue ;
        }
        if( i != j )
            swap1(i,j,n) ;
        for(j = i+1 ; j < n ; j++)
        {
            if( Map[j][t] )
            {
                a[j] ^= a[i] ;
                for(k = t ; k < n ; k++)
                    Map[j][k] ^= Map[i][k] ;
            }
        }
    }
    for( ; i < n ; i++)
        if( a[i] ) return -1 ;
    if( num1 > 0 ) return num1 ;
    for(i = n-1 ; i >= 0 ; i--)
    {
        x[i] = a[i] ;
        for(j = i+1 ; j < n ; j++)
            x[i] ^= (Map[i][j]*x[j]) ;
    }
    return num1 ;
}
int main()
{
    int t , n , i , j , k , min1 , ans , key ;
    scanf("%d", &t) ;
    while( t-- )
    {
        scanf("%d", &n) ;
        for(i = 0 ; i < n ; i++)
        {
            scanf("%s", str[i]) ;
            for(j = 0 ; j < n ; j++)
            {
                if( str[i][j] == 'w' )
                    str[i][j] = '1' ;
                else
                    str[i][j] = '0' ;
            }
        }
        init(n) ;
        key = solve(n*n) ;
        min1 = INF ;
        if( key == 0 )
        {
            ans = 0 ;
            for(i = 0 ; i < n*n ; i++)
                ans += x[i] ;
            min1 = min( min1 , ans ) ;
        }
        else if( key > 0 )
        {
            int t , temp = 1<<key ;
            for(t = 0 ; t < temp ; t++)
            {
                ans = 0 ;
                memset(x,0,sizeof(x)) ;
                for(j = 0 ; j < key ; j++)
                    if( t & (1<<j) )
                    {
                        x[ freex[j] ] = 1 ;
                        ans++ ;
                    }
                for(i = n*n-1 ; i >= 0 ; i--)
                {
                    for(k = 0 ; k < n*n ; k++)
                        if( Map[i][k] )
                            break ;
                    x[k] = a[i] ;
                    for(j = k+1 ; j < n*n ; j++)
                        x[k] ^= ( Map[i][j]*x[j] ) ;
                    ans += x[k] ;
                }
                min1 = min( ans , min1 ) ;
            }
        }
        if( min1 == INF )
            printf("inf\n") ;
        else
            printf("%d\n", min1) ;
    }
    return 0;
}

poj1681--Painter's Problem(高斯消元问题4)

时间: 2024-08-08 09:48:13

poj1681--Painter's Problem(高斯消元问题4)的相关文章

【POJ1681】Painter&#39;s Problem 高斯消元,求最小∑系数的异或方程组

#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/43483547"); } -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 题意: 多组数据. 有个n*n的正方形,然后你要对某些位置进行操作,使得最后灯的状态都变成y.

POJ 1681 Painter&#39;s Problem (高斯消元)

题目地址:POJ 1681 跟前两题几乎一模一样的...不多说了.高斯消元+自由元枚举. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include &

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

http://poj.org/problem? id=1681 求最少经过的步数使得输入的矩阵全变为y. 思路:高斯消元求出自由变元.然后枚举自由变元,求出最优值. 注意依据自由变元求其它解及求最优值的方法. #include <stdio.h> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include

【BZOJ2466】【中山市选2009】树 高斯消元解异或方程组

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44356273"); } 题解: 参照此题解,也是我写的,俩题一样. [POJ1681]Painter's Problem 高斯消元,求最小∑系数的异或方程组 代码: #include <cmath> #include &

POJ 1681 Painter&#39;s Problem (高斯消元)

题目链接 题意: 一个n*n 的木板 ,每个格子 都 可以 染成 白色和黄色,( 一旦我们对也个格子染色 ,他的上下左右 都将改变颜色): 给定一个初始状态 , 求将 所有的 格子 染成黄色 最少需要染几次?  若 不能 染成 输出 inf. 分析: 和1222差不多,唯一的区别是这个题还要求 最短的步数,其实只需要枚举一下最后的x[][]是否为1,即是否需要按下, 由于只有无解或者解唯一,因为按的顺序是没有影响的,所以只要是有解一定唯一,而且最短的情况是每个格子只按一次, 因为按两次以后就变为

POJ 1681 Painter&#39;s Problem 【高斯消元 二进制枚举】

任意门: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 bric

POJ 1681---Painter&#39;s Problem(高斯消元)

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

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to

高斯消元【转】

转载注明出处 高消一直是ACM中高层次经常用到的算法,虽然线性代数已经学过,但高消求解的问题模型及高消模板的应用变化是高消的最复杂之处. 先介绍一下高消的基本原理:引入互联网czyuan的帖子: 高斯消元法,是线性代数中的一个算法,可用来求解线性方程组,并可以求出矩阵的秩,以及求出可逆方阵的逆矩阵. 高斯消元法的原理是: 若用初等行变换将增广矩阵 化为 ,则AX = B与CX = D是同解方程组. 所以我们可以用初等行变换把增广矩阵转换为行阶梯阵,然后回代求出方程的解. 以上是线性代数课的回顾,