\(\\\)

\(Description\)


给出一个\(N\times M\) 的网格,一些位置是障碍,其他位置是空地,求是否存在一个用 \(1\times 2\)的骨牌铺满空地的方案,以及方案是否唯一。

骨牌不能放到网格以外,不能重叠,不能覆盖在障碍物上。

  • \(N,M\le 2000\)

\(\\\)

\(Solution\)


巧妙的思路题。

注意到有一些位置的方案是唯一的。如果一个空格的周围四联通部分只有一个空格,那么必定有一个骨牌要放在这两个格子上。同时,这一次放置可能会影响另一个格子的四联通部分的选择方案。

这就像一个拓扑排序。首先记录每一个点四联通的格子里空地的数量,将数量为\(1\)的放进队列里,然后逐个放置,\(check\) 周围是否有新出现的方案唯一的格子。

最后如果所有空地被填满了,方案就唯一,反之多解。

出题人比较良心,无解和多解都输出 "Not unique" ,所以不需要再判断无解。

\(\\\)

\(Code\)


#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define R register
#define gc getchar
#define N 2010
using namespace std; inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
} char mp[N][N]; int n,m,cnt,num[N][N],deg[N][N]; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; queue<pair<int,int> > q; inline void inq(int x,int y){
for(R int i=0;i<4;++i){
--deg[x+dx[i]][y+dy[i]];
if(deg[x+dx[i]][y+dy[i]]==1) q.push(make_pair(x+dx[i],y+dy[i]));
}
} int main(){
n=rd(); m=rd();
char c=gc();
for(R int i=1;i<=n;++i)
for(R int j=1;j<=m;++j){
while(c!='.'&&c!='*') c=gc();
mp[i][j]=c; c=gc();
}
for(R int i=1;i<=n;++i)
for(R int j=1;j<=m;++j)
if(mp[i][j]=='.'){
deg[i][j]=(mp[i-1][j]=='.')+(mp[i+1][j]=='.')+(mp[i][j-1]=='.')+(mp[i][j+1]=='.');
if(deg[i][j]==1) q.push(make_pair(i,j));
}
while(!q.empty()){
int x=q.front().first;
int y=q.front().second; q.pop();
if(deg[x][y]!=1) continue;
if(mp[x+1][y]=='.'){
mp[x][y]='^';
mp[x+1][y]='v'; inq(x+1,y);
}
if(mp[x-1][y]=='.'){
mp[x-1][y]='^';
mp[x][y]='v'; inq(x-1,y);
}
if(mp[x][y+1]=='.'){
mp[x][y]='<';
mp[x][y+1]='>'; inq(x,y+1);
}
if(mp[x][y-1]=='.'){
mp[x][y-1]='<';
mp[x][y]='>'; inq(x,y-1);
}
}
for(R int i=1;i<=n;++i)
for(R int j=1;j<=m;++j)
if(mp[i][j]=='.'){puts("Not unique");return 0;}
for(R int i=1;i<=n;++i){
for(R int j=1;j<=m;++j) putchar(mp[i][j]);
puts("");
}
return 0;
}

[ CodeForces 515 D ] Drazil and Tiles的更多相关文章

  1. 【codeforces 515D】Drazil and Tiles

    [题目链接]:http://codeforces.com/contest/515/problem/D [题意] 给你一个n*m的格子; 然后让你用1*2的长方形去填格子的空缺; 如果有填满的方案且方案 ...

  2. 【codeforces 516B】Drazil and Tiles

    题目链接: http://codeforces.com/problemset/problem/516/B 题解: 首先可以得到一个以‘.’为点的无向图,当存在一个点没有边时,无解.然后如果这个图边双联 ...

  3. Codeforces Round #292 (Div. 1) B. Drazil and Tiles 拓扑排序

    B. Drazil and Tiles 题目连接: http://codeforces.com/contest/516/problem/B Description Drazil created a f ...

  4. CodeForces - 516B Drazil and Tiles(bfs)

    https://vjudge.net/problem/CodeForces-516B 题意 在一个n*m图中放1*2或者2*1的长方形,问是否存在唯一的方法填满图中的‘.’ 分析 如果要有唯一的方案, ...

  5. Codeforces Round #292 (Div. 1) - B. Drazil and Tiles

    B. Drazil and Tiles   Drazil created a following problem about putting 1 × 2 tiles into an n × m gri ...

  6. Codeforces Round #292 (Div. 2) D. Drazil and Tiles [拓扑排序 dfs]

    传送门 D. Drazil and Tiles time limit per test 2 seconds memory limit per test 256 megabytes Drazil cre ...

  7. [codeforces 516]A. Drazil and Factorial

    [codeforces 516]A. Drazil and Factorial 试题描述 Drazil is playing a math game with Varda. Let's define  ...

  8. Drazil and Tiles CodeForces - 516B (类拓扑)

    Drazil created a following problem about putting 1 × 2 tiles into an n × m grid: "There is a gr ...

  9. Codeforces Round #292 (Div. 1) B. Drazil and Tiles (类似拓扑)

    题目链接:http://codeforces.com/problemset/problem/516/B 一个n*m的方格,'*'不能填.给你很多个1*2的尖括号,问你是否能用唯一填法填满方格. 类似t ...

随机推荐

  1. Linux下使用make install安装的软件如何卸载

    如果是Ubuntu的系统,那么可以使用checkinstall来生成deb包来安装,然后卸载 参考:http://blog.sina.com.cn/s/blog_4178f4bf0101cmt7.ht ...

  2. 断路器监控(Hystrix Dashboard)

    继上一篇http://www.cnblogs.com/EasonJim/p/7613595.html介绍了断路器之后,其实它还提供了一个管理页面来监控这些应用的调用数据. 首先,我是基于上一个例子Zo ...

  3. 【SSH 基础】浅谈Hibernate--入门篇

    Hibernate是什么 Hibernate是一个轻量级的ORMapping框架 ORMapping原理(Object Relational Mapping)就是把对象里面的数据和数据库里面的数据,依 ...

  4. 经典面试题回答——学习Java基础的目的

    本系列知识解释:相信每个学习Java的人都是从JavaSE開始的,也就是Java基础開始. 可是却并不清楚学习Java基础究竟有什么用?        首先我来回答这个问题,学习Java基础是有两个目 ...

  5. 2016/2/18 html 图片热点,网页划区,拼接,表单

    ①图片热点 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果. 显示 ②网页划区 在一个网页里,规划出一个区域用来展示另一个网页的内容. ③网页拼接 在一个网络页面内,规划 ...

  6. 扩展欧几里得模板&逆元求法

    拓展欧几里得: 当 gcd ( a , b )= d 时,求绝对值和最小的 x , y 使得 x * a + y * b = d : d = gcd ( a , b ) = gcd ( b , a m ...

  7. poj 3683(2-sat+拓扑排序)

    Priest John's Busiest Day Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11127   Accep ...

  8. BZOJ_4800_[Ceoi2015]Ice Hockey World Championship_双指针

    BZOJ_4800_[Ceoi2015]Ice Hockey World Championship_双指针 Description 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. Inpu ...

  9. ZOJ1081 Points Within 点和多边形的位置关系

    ZOJ1081 给一个点和一个多边形 判断点在多边形内(边上)还是在多边形外 在多边形外的点引一条射线必然穿过多边形的两条边 而在多边形内的点则不一定. 当然凹多边形有特殊情况 但是总能找到对应位置关 ...

  10. POJ1808 平方(二次)同余方程

    POJ1808  给定一个方程 x*x==a(mod p) 其中p为质数 判断是否有解 程序中 MOD_sqr()返回整数解 无解返回-1 数学证明略 #include<iostream> ...