概述
题目链接: http://www.spoj.com/problems/NWERC11D/
Piece it together
Tom has developed a special kind of puzzle: it involves a whole bunch of identical puzzle pieces. The pieces have the shape of three adjoint squares in an L-shape. The corner square is black, the two adjacent squares are white.
The puzzler is given a pattern of black and white squares in a rectangular grid. The challenge is to create that pattern using these pieces. The pieces can be rotated, but must not overlap.
Tom has already designed a few nice patterns, but he needs to find out if they can be constructed with the pieces at all. Rather than trying to test this for each pattern by hand, he wants to write a computer program to determine this for him. Can you help him?
Input
On the first line a positive integer: the number of test cases, at most 100. After that per test case:
- one line with two integers n and m (1 ≤ n,m ≤ 500): the height and width of the grid containing the pattern, respectively.
- n lines, each containing m characters, denoting the grid. Each character is ‘B’, ‘W’, or ‘.’, indicating a black, white or empty square respectively.
The grid contains at least one black or white square.
Output
Per test case:
- one line with either “YES” or “NO”, indicating whether or not it is possible to construct the pattern with the puzzle pieces. You may assume that there is an infinite supply of pieces.
Sample in- and output
Input | Output |
2 3 4 BWW. WWBW ..WB 3 3 W.. BW. WBW | YES NO |
题意:
用L型模版匹配给定矩阵
(模版为左下角黑色,其他白色的2块)
问:
能否完美匹配矩阵
思路:
把黑块拆成2点, A点匹配上下的白色, A'匹配左右的白色
这里把二分匹配中 memset(T,0,sizeof(T)) ; 优化成 Time
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdio.h>
#define ll int
#define N 500010
using namespace std;
inline ll Max(ll a, ll b){return a>b?a:b;}struct node{
int to, nex;
}edge[N*2];
int head[N],edgenum ;
void addedge(int u, int v){
node E = {v, head[u]};
edge[ edgenum ] = E;
head[u] = edgenum ++;
}int xn, T[N], lef[N], Time;
bool
IsB[N];int match(int x){
for(int i = head[x]; i!=-1; i = edge[i].nex)
{
int v = edge[i].to;
if(T[v] == Time)continue;
T[v] = Time;
if(lef[v] == -1 || match(lef[v]))
{
lef[v] = x;
return 1;
}
}
return 0;
}int solve(){
int ans = 0;
memset(lef, -1, sizeof(lef));
for(int i = 0; i <= xn; i++)
if(IsB[i])
{ Time++; ans += match( i ); }
return ans ;
}int n, m;
int map[505][505],step[4][2] = {0,1,0,-1,1,0,-1,0};
char s[505];bool Inmap(int x,int y){ return (x>=0 && x<n && y>=0 && y<m)? true : false;}
void Have_map(){
memset(head, -1, sizeof(head)),
edgenum = 0;
memset(IsB, 0, sizeof(IsB));
xn = -1;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(map[i][j] == 1)
for(int k = 0; k < 4; k++)
{
int nowx = i+step[k][0], nowy = j + step[k][1];
if(Inmap(nowx, nowy) && map[nowx][nowy]==2)
{
if(k==0 || k==1)
addedge(i*m+j, nowx*m + nowy);
else
addedge(n*m + i*m+j, nowx*m + nowy);
IsB[i*m+j] = IsB[n*m + i*m+j] = true;
xn = n*m + i*m +j;
}
}
}
int main(){
int t;scanf("%d",&t);
Time = 1;
memset(T, 0, sizeof(T)); while(t--){
memset(map, 0, sizeof(map));
scanf("%d %d",&n,&m);
int B = 0, W = 0;
for(int i = 0; i < n; i++)
{
scanf("%s",s);
for(int j = 0; j < m; j++)
{
if(s[j] == 'B')
B++, map[i][j] = 1;
else if(s[j] == 'W')
W++, map[i][j] = 2;
}
}
if(W != B*2){ printf("NOn");continue;}
Have_map();
printf("%sn", (solve() == W)? "YES":"NO");
}
return 0;
}
最后
以上就是可耐巨人为你收集整理的Uva 1514 && spoj 9890 拆点匹配L模板 + 时间戳优化的全部内容,希望文章能够帮你解决Uva 1514 && spoj 9890 拆点匹配L模板 + 时间戳优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复