题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=307
题意:N*M的01矩阵 A,(N-1)*(M-1)的矩阵B,其中B[i][j]=A[i][j]+A[i+1][j]+A[i][j+1]+A[i+1][j+1].给出B输出A。
思路:
这样,对于a[i][j](1<=i<=n-1,1<=j<=m-1),只是由a[n][m],a[n][j]和a[i][m]所限制。因此,枚举a[n][m],接着根据a[n][j]和a[i][m]计算出a[i][j],不是1和0时建立2-SAT。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <map>
#include <sstream>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)>=0?(x):-(x))
#define i64 long long
#define u32 unsigned int
#define u64 unsigned long long
#define clr(x,y) memset(x,y,sizeof(x))
#define CLR(x) x.clear()
#define ph(x) push(x)
#define pb(x) push_back(x)
#define Len(x) x.length()
#define SZ(x) x.size()
#define PI acos(-1.0)
#define sqr(x) ((x)*(x))
#define FOR0(i,x) for(i=0;i<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define DOW0(i,x) for(i=x;i>=0;i--)
#define DOW1(i,x) for(i=x;i>=1;i--)
#define DOW(i,a,b) for(i=a;i>=b;i--)
using namespace std;
void RD(int &x){scanf("%d",&x);}
void RD(i64 &x){scanf("%I64d",&x);}
void RD(u32 &x){scanf("%u",&x);}
void RD(double &x){scanf("%lf",&x);}
void RD(int &x,int &y){scanf("%d%d",&x,&y);}
void RD(i64 &x,i64 &y){scanf("%I64d%I64d",&x,&y);}
void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}
void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}
void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}
void RD(i64 &x,i64 &y,i64 &z){scanf("%I64d%I64d%I64d",&x,&y,&z);}
void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}
void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}
void RD(char &x){x=getchar();}
void RD(char *s){scanf("%s",s);}
void RD(string &s){cin>>s;}
void PR(int x) {printf("%d\n",x);}
void PR(i64 x) {printf("%lld\n",x);}
void PR(u32 x) {printf("%u\n",x);}
void PR(u64 x) {printf("%llu\n",x);}
void PR(double x) {printf("%.4lf\n",x);}
void PR(char x) {printf("%c\n",x);}
void PR(char *x) {printf("%s\n",x);}
void PR(string x) {cout<<x<<endl;}
struct node
{
int v,next;
};
const int MAX=1205;
const int MAXE=1000005;
node edges[MAXE];
int head[MAX],e;
int dfn[MAX],low[MAX],visit[MAX],color[MAX],col[MAX];
int n,index,cnt;
stack<int> S;
int deg[MAX],ans[MAX],p[MAX];
int head1[MAX],e1;
node edges1[MAXE];
int B[MAX][MAX],C[MAX][MAX],A[MAX][MAX],N,M;
void Add(int u,int v)
{
edges[e].v=v;
edges[e].next=head[u];
head[u]=e++;
}
void Add1(int u,int v)
{
edges1[e1].v=v;
edges1[e1].next=head1[u];
head1[u]=e1++;
}
void Tarjan(int u)
{
int i,v;
low[u]=dfn[u]=++index;S.push(u);visit[u]=1;
for(i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(visit[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
cnt++;
do
{
v=S.top();
S.pop();
visit[v]=0;
color[v]=cnt;
}while(u!=v);
}
}
void init()
{
memset(deg,0,sizeof(deg));
memset(head1,-1,sizeof(head1));
e1=0;
int i,u,v,x,y;
for(u=1;u<=2*n;u++)
{
for(i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
if(color[v]!=color[u])
{
x=color[v];
y=color[u];
Add1(x,y);
deg[y]++;
}
}
}
while(!S.empty()) S.pop();
for(i=1;i<=cnt;i++) if(!deg[i]) S.push(i);
memset(p,0,sizeof(p));
while(!S.empty())
{
u=S.top();
S.pop();
if(!p[u]) p[u]=1,p[col[u]]=-1;
for(i=head1[u];i!=-1;i=edges1[i].next)
{
v=edges1[i].v;
if(--deg[v]==0) S.push(v);
}
}
}
int TWO_ST()
{
int i;
memset(dfn,0,sizeof(dfn));
memset(visit,0,sizeof(visit));
index=cnt=0;
while(!S.empty()) S.pop();
for(i=1;i<=2*n;i++) if(!dfn[i]) Tarjan(i);
for(i=1;i<=n;i++)
{
if(color[i*2-1]==color[i*2]) return 0;
col[color[i*2-1]]=color[i*2];
col[color[i*2]]=color[i*2-1];
}
init();
return 1;
}
int ok(int x)
{
return x==0||x==1;
}
#define L(x) ((x)*2-1)
#define R(x) ((x)*2)
int judge(int q)
{
int i,j,k,t,x,y,z,u,v;
clr(C,0);
for(i=N-1;i>=1;i--) for(j=M-1;j>=1;j--)
{
C[i][j]=B[i][j]-C[i+1][j]-C[i][j+1]-C[i+1][j+1];
}
clr(head,-1);
e=0;
FOR1(i,N-1) FOR1(j,M-1)
{
x=(M-j)%2?-1:1;
y=(N-i)%2?-1:1;
z=(N-i+M-j+1)%2?-1:1;
FOR0(k,2) FOR0(t,2) if(!ok(C[i][j]+x*k+y*t+z*q))
{
u=k?L(i):R(i);
v=!t?L(j+N-1):R(j+N-1);
Add(u,v);
u=t?L(j+N-1):R(j+N-1);
v=!k?L(i):R(i);
Add(u,v);
}
}
n=N+M-2;
if(!TWO_ST()) return 0;
A[N][M]=q;
FOR1(i,N-1) A[i][M]=(p[color[L(i)]]==1);
FOR1(i,M-1) A[N][i]=(p[color[L(i+N-1)]]==1);
for(i=N-1;i>=1;i--) for(j=M-1;j>=1;j--)
{
A[i][j]=B[i][j]-A[i+1][j]-A[i][j+1]-A[i+1][j+1];
}
FOR1(i,N)
{
FOR1(j,M) printf("%d",A[i][j]);
puts("");
}
return 1;
}
int main()
{
scanf("%d%d",&N,&M);
int i,j;
for(i=1;i<N;i++) for(j=1;j<M;j++) scanf("%1d",&B[i][j]);
if(judge(0)||judge(1)) return 0;
puts("CORRUPT");
return 0;
}