POJ2585
题意:
有一个4*4的显示器,上面可以出现9种2*2的图片,这些图片可以相互覆盖,问输入的图片可否由那九种图片堆叠出来
题解
初始化基本信息,拓扑排序判断有无环出现
代码:
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <queue>
using namespace std ;
int MAP[5][5] ;//储存输入图片信息
int edge[10][10] ;//邻接矩阵
int in[10] ;//储存入度
string windows[5][5] ;//每个节点可以包含的字符
int visit[10] ;//某种字符是否出现
int t ;//共有几种字符出现
void init()
{
int i , j , k ;
for(i = 0 ; i <5 ; i ++)
for(j = 0 ; j < 5 ; j ++)
windows[i][j].erase();
for(k = 1 ; k <= 9 ; k ++)
{
i = (k - 1)/3;
j = (k - 1)%3;
windows[i][j] +=char(k) ;
windows[i][j+1] +=char(k) ;
windows[i+1][j] +=char(k) ;
windows[i+1][j+1] +=char(k) ;
}
}
void build()
{
int i , j , k ;
for (i = 0; i < 4; ++i)
{
for(j = 0; j < 4 ; j ++)
{
for(k = 0; k <windows[i][j].length();k++)
{
if(!edge[MAP[i][j]][windows[i][j][k]] && (MAP[i][j]!=windows[i][j][k]))
{
edge[MAP[i][j]][windows[i][j][k]] = 1;
in[windows[i][j][k]] ++ ;
}
}
}
}
}
int topo()
{
int i , j , k ;
for (i = 0; i < t; ++i)
{
k = 1;
while(!visit[k] || (k<=9&&in[k]>0)) k++;
if(k>9) return 0 ;
visit[k] = 0;
for(j = 1 ; j < 10 ; j ++)
{
if(visit[j] && edge[k][j])
in[j] -- ;
}
}
return 1 ;
}
int main()
{
char words[20] ;
init() ;
while(cin >> words)
{
if(words[3] == 'O') break ;
memset(in , 0 , sizeof(in)) ;
memset(visit , 0 , sizeof(visit)) ;
memset(edge , 0 , sizeof(edge)) ;
t = 0 ;
for(int i = 0 ; i <= 3 ; i ++)
for (int j = 0; j <= 3; j ++)
{
scanf("%d" , &MAP[i][j]) ;
if (!visit[MAP[i][j]])
{
t ++ ;
visit[MAP[i][j]] = 1 ;
}
}
build() ;
if(topo())
puts("THESE WINDOWS ARE CLEAN");
else
puts("THESE WINDOWS ARE BROKEN");
cin>>words;
}
return 0;
}