poj 1681

原创 2015年07月08日 21:18:00

题目描述:

解法一:和以前摆格子的题目差不多.但是不一样.这个十字只有一种摆放方式,如果确定了上一行的颜色,那么这一行怎么摆就确定了.因此只需要确定第一行,然后往下走就行.i,j是十字的中心.(ij是否放只与它的上一个有关,并且只有一种放法)
解法二:高斯消元.重点是当有自由变元的时候枚举然后倒着推上去..

题解:

rt

重点:

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)

typedef long long ll;

using namespace std;

const int maxn = 300+100;
const int INF = 1e9;
int dx[]= {-1, 0, 1, 0}, dy[]= {0, 1, 0, -1};
int a[maxn][maxn], x[maxn];
int equ, var;
char s[maxn][maxn];
int free_x[maxn];
int free_num;
int n;

int gauss()
{
    free_num=0;
    int k, col;
    for(k=0, col=0; k<equ&&col<var; k++,col++)
    {
        int max_k=k;
        for(int i=k+1; i<equ; i++)
        {
            if(abs(a[i][col])>abs(a[max_k][col]))
            {
                max_k = i;
            }
        }
        if(a[max_k][col]==0)
        {
            free_x[free_num++]=col;
            k--;
            continue;
        }
        if(k!=max_k)
        {
            for(int i=col; i<=var; i++)
            {
                swap(a[k][i], a[max_k][i]);
            }
        }
        for(int i=k+1; i<equ; i++)
        {
            if(a[i][col])
            {
                for(int j=col+1; j<=var; j++)
                {
                    a[i][j]^=a[k][j];
                }
                a[i][col]=0;
            }
        }
    }
    for(int i=k; i<equ; i++)
    {
        if(a[i][col])
        {
            return -1;
        }
    }
    if(k==var)
    {
        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]);
            }
        }
        int ans=0;
        for(int i=0; i<var; i++)
        {
            ans += x[i];
        }
        return ans;
    }
    int S = (1<<(var-k))-1;
    int ans = INF;
    int cnt;
    for(int sta=0; sta<=S; sta++)
    {
        cnt=0;
        for(int i=0; i<free_num; i++)
        {
            if(((1<<i)&sta))
            {
                x[free_x[i]]=1;
                cnt++;
            }
            else
            {
                x[free_x[i]]=0;
            }
        }
        for(int i=k-1; i>=0; i--)
        {
            int index=i;
            for(int j=i; j<var; j++)
            {
                if(a[i][j]!=0)
                {
                    index=j;
                    break;
                }
            }
            x[index]=a[i][var];
            for(int j=index+1; j<var; j++)
            {
                x[index]^=(a[i][j]&x[j]);
            }
            cnt += x[index];
        }
        ans = min(cnt, ans);
    }
    return ans;
}

int check(int x, int y)
{
    if(x>=0&&x<n&&y>=0&&y<n)
        return 1;
    return 0;
}
void solve()
{
    equ=n*n;
    var=equ;
    CLR(a);
    CLR(x);
    REP(i, 0, n)
    {
        REP(j, 0, n)
        {
            int tmp=i*n+j;
            if(s[i][j]=='y')
            {
                a[tmp][var]=0;
            }
            else
            {
                a[tmp][var]=1;
            }
            a[tmp][tmp]=1;
            for(int k=0; k<4; k++)
            {
                int newI=i+dx[k], newJ=j+dy[k];
                if(check(newI, newJ))
                {
                    int goal=newI*n+newJ;
                    a[goal][tmp]=1;
                }
            }
        }
    }
    int ans=gauss();
    if(ans==-1)
    {
        printf("inf\n");
    }
    else
    {
        printf("%d\n", ans);
    }
}

int main()
{
    //freopen("4Din.txt", "r", stdin);
    //freopen("4Dout.txt", "w", stdout);
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        REP(i, 0, n)
        {
            scanf("%s", s[i]);
        }
        solve();
    }
    return 0;
}

POJ1681高消+搜索

Painter's Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3484 ...

poj-1681【矩阵连乘】

题意是:给你一序列数,每次抽出一个数字(两端除外),抽取的数乘以旁边两个数作为此次操作的积分,抽到只剩两个数为止。求总积分最小。 题目给的数据:10 1 50 50 20 5 可以看成给了 10*1 ...

poj 1681 Painter's Problem 【高斯消元 + 状压枚举自由变元】

Painter's Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5075   Accepted...

Poj1681 【枚举】

#include #include #include #include int map[16][16], temp[16][16], row[16]; int n, min, cnt; void me...

POJ 1681 画家问题

Painter’s Problem Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6303 Accepte...

POJ1681-Painter's Problem

Description There is a square wall which is made of n*n small square bricks. Some bricks are whit...

[POJ1681]画家问题

描述 有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使。当他用画笔涂画第(i, j)个位置的砖时, 位置(...

poj 1681

   题目意思很简单,很poj 1222其实是一模一样的,只是要会判断是否存在无解的情况。当用高斯法化简了矩阵以后,再答案矩阵的那部分若有值不为0,则无解(具体原来可以见czyuan神的blog或者去...

【高斯消元】poj 1681 Painter's Problem

http://poj.org/problem?id=1681 高斯消元求最小步数,二进制枚举0-1变元,统计和的最小值 /* poj 1222 高斯消元-枚举自由变元 题意: 0-...

POJ 1681 Painter's Problem(画家问题)

总时间限制: 1000ms 内存限制: 65536kB 描述有一个正方形的墙,由N*N个正方形的砖组成,其中一些砖是白色的,另外一些砖是黄色的。Bob是个画家,想把全部的砖都涂成黄色。但他的画笔不好使...
  • tp7309
  • tp7309
  • 2016年10月26日 20:19
  • 598
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 1681
举报原因:
原因补充:

(最多只允许输入30个字)