POJ2585 Window Pains [拓扑排序]

题意:

一个屏幕要同时打开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;
}


你可能感兴趣的:(windows)