题意:
一个屏幕要同时打开9个窗口,每个窗口是2*2的矩阵,整个屏幕大小是9*9,每个窗口位置固定。
但是是否被激活(即完整显示出来)不确定。
给定屏幕状态,问是否可以实现显示。
思路:
覆盖问题。很裸的拓扑排序。
其实看数据量也可以猜到暴力也可以。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define Abs(a) ((a)>0?(a):(-(a)))
#define llong long long int
using namespace std;
const int N=15;
const int inf=(1<<30);
int mat[5][5];
int xhas[10]={0,1,2,3,1,2,3,1,2,3};
int yhas[10]={0,1,1,1,2,2,2,3,3,3};
int my[4]={0,0,1,1};
int mx[4]={0,1,0,1};
int indgr[N];
int line[N][N];
void addedge(int u,int v)
{
if(!line[u][v])
{
line[u][v]=true;
indgr[v]++;
}
}
bool toposort()
{
int sum=0;
queue<int> que;
for(int i=1;i<=9;i++)
if(!indgr[i])
que.push(i);
while(!que.empty())
{
int now=que.front();
que.pop();
sum++;
//printf("%d",now);
for(int i=1;i<=9;i++)
{
if(line[now][i])
{
indgr[i]--;
if(!indgr[i])
{
que.push(i);
}
}
}
}
if(sum==9)
return true;
return false;
}
void solve()
{
memset(line,0,sizeof(line));
memset(indgr,0,sizeof(indgr));
for(int i=1;i<=9;i++)
{
int x=xhas[i];
int y=yhas[i];
for(int j=0;j<4;j++)
{
int xx=x+mx[j];
int yy=y+my[j];
if(mat[yy][xx]!=i)//覆盖在i之上
{
addedge(mat[yy][xx],i);
}
}
}
if(toposort())
printf("THESE WINDOWS ARE CLEAN\n");
else
printf("THESE WINDOWS ARE BROKEN\n");
}
int main()
{
char str[15];
while(scanf("%s",str),str[0]=='S')
{
for(int i=1;i<=4;i++)
for(int j=1;j<=4;j++)
{
scanf("%d",mat[i]+j);
}
solve();
scanf("%s",str);
}
return 0;
}