【CH6801】棋盘覆盖
题目大意:给定一个 N*N 的棋盘,棋盘上有些位置不能防止任何东西,现用 1*2 的骨牌填充棋盘,问最多能铺多少块骨牌。
题解:由于骨牌只能覆盖相邻的两个格子,那么按照对角线进行划分的格子可以保证一定不会被骨牌覆盖。因此,可以将骨牌看成边,每个格子可以与周围的四个合法的格子建立边。每个对角线上的点,以及隔着一组对角线的对角线之间不会被覆盖,因此可以作为二分图的点集合。建模之后直接用匈牙利算法进行匹配即可。
代码如下
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=1e4+10;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll sqr(ll x){return x*x;}
inline ll read(){
ll x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
vector<int> G[maxn];
int match[maxn];bool vis[maxn];
int n,m,mpp[101][101],ans;
inline bool right(int r,int c){return r>=1&&r<=n&&c>=1&&c<=n&&!mpp[r][c];}
inline int get(int x,int y){return n*(x-1)+y;}
void read_and_parse(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
mpp[x][y]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)if(!mpp[i][j]&&((i+j)&1))
for(int k=0;k<4;k++)
if(right(i+dx[k],j+dy[k])){
int x=get(i,j),y=get(i+dx[k],j+dy[k]);
G[x].pb(y),G[y].pb(x);
}
}
bool dfs(int u){
for(auto v:G[u])if(!vis[v]){
vis[v]=1;
if(!match[v]||dfs(match[v]))
return match[v]=u,1;
}
return 0;
}
void solve(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(((i+j)&1)||mpp[i][j])continue;
memset(vis,0,sizeof(vis));
if(dfs(get(i,j)))++ans;
}
printf("%d\n",ans);
}
int main(){
read_and_parse();
solve();
return 0;
}
【CH6801】棋盘覆盖的更多相关文章
- CH6801 棋盘覆盖
6801 棋盘覆盖 0x60「图论」例题 描述 给定一个N行N列的棋盘,已知某些格子禁止放置.求最多能往棋盘上放多少块的长度为2.宽度为1的骨牌,骨牌的边界与格线重合(骨牌占用两个格子),并且任意两张 ...
- 「CH6801」棋盘覆盖
「CH6801」棋盘覆盖 传送门 考虑将棋盘黑白染色,两个都无障碍的相邻的点之间连边,边的容量都为1,然后就求一次最大匹配即可 参考代码: #include <cstring> #incl ...
- bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link
2706: [SDOI2012]棋盘覆盖 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 255 Solved: 77[Submit][Status] ...
- NYOJ 45 棋盘覆盖
棋盘覆盖 水题,题不难,找公式难 import java.math.BigInteger; import java.util.Scanner; public class Main { public s ...
- 棋盘覆盖(大数阶乘,大数相除 + java)
棋盘覆盖 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的 ...
- NYOJ 45 棋盘覆盖 模拟+高精度
题意就不说了,中文题... 小白上讲了棋盘覆盖,于是我就挖了这题来做. 棋盘覆盖的推导不是很难理解,就是分治的思想,具体可以去谷歌下. 公式就是f(k) = f(k - 1) * 4 + 1,再化解下 ...
- 棋盘覆盖(一) ACM
棋盘覆盖 描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的2×2方格(图2为其中缺右下角的一个),去覆盖2k×2k未被覆盖过的方格,求 ...
- 棋盘覆盖问题(算法分析)(Java版)
1.问题描述: 在一个2k×2k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有种情形.因而对任何 k≥0,有4k种不 ...
- CODEVS 2171 棋盘覆盖
2171 棋盘覆盖 给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖. 错误日志: 直接在模板上调整 \(maxn\) 时没有在相应邻接表数 ...
- 递归与分治策略之棋盘覆盖Java实现
递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分 ...
随机推荐
- 使用cmd命令删除文件夹下所有文件
rmdir 删除整个目录 好比说我要删除 222 这个目录下的所有目录和档案,这语法就是: rmdir /s/q 222 其中: /s 是代表删除所有子目录跟其中的档案. /q 是不要它在删除档案或目 ...
- python之路--进程内容补充
一. 进程的其他方法 进程id, 进程名字, 查看进程是否活着(is_alive()), terminate()发送结束进程的信号 import time import os from multipr ...
- mysql对身份证号码进行脱敏处理
select * from test 格式:INSERT(str,pos,len,newstr) 解释: str:查询的例 pos:起始位置 len:从起始位置开始被后面newstr替换的长度 new ...
- AI算法第一天【概述与数学初步】
1. 机器学习的定义: 机器从数据中学习出规律和模式,以应用在新数据上作出预测的任务 2.学习现象: (1)语言文字的认知识别 (2)图像,场景,物体的认知和识别 (3)规则:下雨天要带雨伞 (4)复 ...
- Java ME之Android开发从入门到精通
1. 搭建Android开发环境 方式一:使用ADT插件安装 ADT插件的下载与安装,ADT插件获取网址:http://www.androiddevtools.cn/ 下载好的ADT插件如图所示: 在 ...
- oracle 触发器详情
Oracle PL/SQL编程之八: 把触发器说透 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触 ...
- struts2 核心过滤器的配置
<!-- struts2 过滤器核心配置--> <filter> <filter-name>struts2</filter-name> <filt ...
- servlet篇 之servlet实现
一:如何写一个servlet 实现/继承 如下 接口/类 Servlet 接口 有五个抽象方法 GenericServlet 抽象类 有一个抽象方法 HttpServlet 抽象类 ...
- Cmder使用ls中文显示乱码解决方案
操作系统:Windows 7 旗舰版 Cmder:1.3.2 默认配置不支持使用ls显示中文命名的文件列表. 解决方法: 按下Win+Alt+P打开设置. 在StartUp - Environment ...
- python之旅六【第七篇】面向对象
面向对象三大特性 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象:对函数进行分类和封装,让开发“更快更好更强... 面向对象编程 ...