【NKOJ1987 POJ1681】手机游戏(Painter's Problem) 高斯消元

高斯消元,消来消去真有趣,突然想去玩祖玛。

POJ传送门http://poj.org/problem?id=1681

NKOJ传送门http://oi.nks.edu.cn/zh/Problem/Details/1987

一个高斯消元解异或方程组板题。

真的没有什么好说的。就说说时间复杂度。看似O(n6)的时间复杂度,但我们可以注意到,每一个点最多关联上下左右自己5个方程式,也就说实际上它的时间复杂度是O(n4)加上一个常数(可见大概为5)。

记得要枚举自由元!用DFS比较好理解,也有状压的写法,DFS原型来自ciocio学长。

#include<cstring>
#include<iostream>
#include<cstdio>
using namespace std;
int n,N,X[2005]; 
int A[2005][2005];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
int aha=0;
int minn; int num[2005];
int ans[2005];
void dfs(int x,int y)
{
	if(x==0&&y==0) 
	{
		int cnt=0;
		for(int i=1;i<=N;i++) cnt+=ans[i];
		minn=min(minn,cnt);
		return;
	}
	if(num[x]==y)
	{
		ans[y]=A[x][N+1];
		for(int i=y+1;i<=N;i++) ans[y]^=(A[x][i]&ans[i]);
		dfs(x-1,y-1);
	}
	else
	{
		ans[y]=1; dfs(x,y-1);
		ans[y]=0; dfs(x,y-1);
	}
}// from ciocio
void gauss()
{
    int x,y,maxr;
    for(x=1,y=1;x<=N&&y<=N;x++,y++)
    {
        for(maxr=x;maxr<=N&&(!A[maxr][y]);maxr++);
        if(maxr==N+1) { x--;  continue; }
        if(maxr!=x)
        for(int j=y;j<=N+1;j++) swap(A[x][j],A[maxr][j]);
        num[x]=y;
		for(int i=x+1;i<=N;i++)
        {
            if(A[i][y])
            for(int j=y;j<=N+1;j++) A[i][j]^=A[x][j];
        }
    }
    for(int i=x;i<=N;i++) if(A[i][N+1])  { printf("inf\n"); return; };   
	minn=0x3f3f3f3f;
    dfs(x-1,N);
    printf("%d\n",minn);
}
int main()
{
    char ch;
    scanf("%d",&n);
    N=n*n;
    for(int i=1;i<=n*n;i++) A[i][n*n+1]=1;
    int nx,ny;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            for(int tt=0;tt<4;tt++)
            {
                nx=i+dx[tt]; ny=j+dy[tt];
                if(nx>=1&&ny>=1&&nx<=n&&ny<=n) 
                {
                    A[(i-1)*n+j][(nx-1)*n+ny]=1;
                }
            }
            A[(i-1)*n+j][(i-1)*n+j] = 1;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            ch=getchar();
            while(ch!='y'&&ch!='w') ch=getchar();
            if(ch=='y') A[(i-1)*n+j][N+1]=0;
            else A[(i-1)*n+j][N+1]=1;
        } 
    }
    gauss();
}

 

 

posted @ 2018-04-08 23:21  Newuser233  阅读(5)  评论(0)    收藏  举报