关闭

poj 1681

124人阅读 评论(0) 收藏 举报
分类:

题目描述:

解法一:和以前摆格子的题目差不多.但是不一样.这个十字只有一种摆放方式,如果确定了上一行的颜色,那么这一行怎么摆就确定了.因此只需要确定第一行,然后往下走就行.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;
}
0
0

猜你在找
【直播】机器学习&数据挖掘7周实训--韦玮
【套餐】系统集成项目管理工程师顺利通关--徐朋
【直播】3小时掌握Docker最佳实战-徐西宁
【套餐】机器学习系列套餐(算法+实战)--唐宇迪
【直播】计算机视觉原理及实战--屈教授
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之矩阵--黄博士
【套餐】微信订阅号+服务号Java版 v2.0--翟东平
【直播】机器学习之凸优化--马博士
【套餐】Javascript 设计模式实战--曾亮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:42923次
    • 积分:2401
    • 等级:
    • 排名:第15411名
    • 原创:206篇
    • 转载:0篇
    • 译文:0篇
    • 评论:1条
    最新评论