\(\\\)

\(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. mysql 时间戳格式化函数from_unixtime使用说明

    我们一般使用字段类型int(11)时间戳来保存时间,这样方便查询时提高效率.但这样有个缺点,显示的时间戳,非常难知道真实日期时间. mysql提供了一个时间戳格式化函数from_unixtime来转换 ...

  2. 自己构建的Lumbda表达式

    自己构建的Lumbda表达式 定义接口: package com.stono.lambda; public interface Add { public void add(int x, int y); ...

  3. 使用Maven对JAVA程序打包-带主类、带依赖

    使用Maven对JAVA程序打包-带主类.带依赖 http://blog.csdn.net/strongyoung88/article/details/54097830

  4. Vue中对获取的数据进行重新排序

    var Enumerable = require('linq'); // 使用linq 按照RegisterID排序listJust是自己定义的数组,来接收数据.listJust: [] addDat ...

  5. node-load module

    javscript :脚本建共享全局名称空间(全局污染). node:实现CommonJS(公共)模块标准. Node加载模块,有两种方式: 1.通过名称 除非是核心模块,否则被引用的模块最后都会映射 ...

  6. 扩展GCD 中国剩余定理(CRT) 乘法逆元模版

    extend_gcd: 已知 a,b (a>=0,b>=0) 求一组解 (x,y) 使得 (x,y)满足 gcd(a,b) = ax+by 以下代码中d = gcd(a,b).顺便求出gc ...

  7. 任务调度(三)——Timer的替代品ScheduledExecutorService简单介绍

    先前的两篇博文<任务调度(一)--jdk自带的Timer>和<任务调度(二)--jdk自带的Timer 动态改动任务运行计划>中,简介了一下Timer,能够实现几本的功能.可是 ...

  8. openstack (1)----- NTP 时间同步服务

    一.标准时间 1.地球分为东西十二个区域,共计24个时区 2.格林威治作为全球标准时间即(GMT时间),东时区以格林威治时区进行加,而西时区则进行减 3.地球的轨道并非正圆,在加上自传速度逐年递减,因 ...

  9. 开发人员调试工具Chrome Workspace

    Workspace是个什么样的东西呢?他可以在开发人员工具中调试改动js或者css同一时候自己主动保存文件.可以避免开发人员在工具中调试好,再到编辑器中改动一次代码的反复操作,可以提高一定的效率 配置 ...

  10. c++运算符重载以及一些基本概念

    c++primer第四版435 1.赋值( = ), 下标( [ ] ) ,调用 (  ( )  ), 成员訪问箭头 (->)等操作符必须定义为成员,定义为非成员时,编译器报错 2. 像赋值一样 ...