poj 1681

来源:互联网 发布:公司网络使用管理制度 编辑:程序博客网 时间:2024/06/05 18:30

题目描述:

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