题目大意:给定一个 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】棋盘覆盖的更多相关文章

  1. CH6801 棋盘覆盖

    6801 棋盘覆盖 0x60「图论」例题 描述 给定一个N行N列的棋盘,已知某些格子禁止放置.求最多能往棋盘上放多少块的长度为2.宽度为1的骨牌,骨牌的边界与格线重合(骨牌占用两个格子),并且任意两张 ...

  2. 「CH6801」棋盘覆盖

    「CH6801」棋盘覆盖 传送门 考虑将棋盘黑白染色,两个都无障碍的相邻的点之间连边,边的容量都为1,然后就求一次最大匹配即可 参考代码: #include <cstring> #incl ...

  3. bzoj 2706: [SDOI2012]棋盘覆盖 Dancing Link

    2706: [SDOI2012]棋盘覆盖 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 255  Solved: 77[Submit][Status] ...

  4. NYOJ 45 棋盘覆盖

    棋盘覆盖 水题,题不难,找公式难 import java.math.BigInteger; import java.util.Scanner; public class Main { public s ...

  5. 棋盘覆盖(大数阶乘,大数相除 + java)

    棋盘覆盖 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的 ...

  6. NYOJ 45 棋盘覆盖 模拟+高精度

    题意就不说了,中文题... 小白上讲了棋盘覆盖,于是我就挖了这题来做. 棋盘覆盖的推导不是很难理解,就是分治的思想,具体可以去谷歌下. 公式就是f(k) = f(k - 1) * 4 + 1,再化解下 ...

  7. 棋盘覆盖(一) ACM

    棋盘覆盖 描述 在一个2k×2k(1<=k<=100)的棋盘中恰有一方格被覆盖,如图1(k=2时),现用一缺角的2×2方格(图2为其中缺右下角的一个),去覆盖2k×2k未被覆盖过的方格,求 ...

  8. 棋盘覆盖问题(算法分析)(Java版)

    1.问题描述: 在一个2k×2k个方格组成的棋盘中,若有一个方格与其他方格不同,则称该方格为一特殊方格,且称该棋盘为一个特殊棋盘.显然特殊方格在棋盘上出现的位置有种情形.因而对任何 k≥0,有4k种不 ...

  9. CODEVS 2171 棋盘覆盖

    2171 棋盘覆盖 给出一张nn(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少12的多米诺骨牌进行掩盖. 错误日志: 直接在模板上调整 \(maxn\) 时没有在相应邻接表数 ...

  10. 递归与分治策略之棋盘覆盖Java实现

    递归与分治策略之棋盘覆盖 一.问题描述 二.过程详解 1.棋盘如下图,其中有一特殊方格:16*16 . 2.第一个分割结果:8*8 3.第二次分割结果:4*4 4.第三次分割结果:2*2 5.第四次分 ...

随机推荐

  1. MyBatis全局配置文件的各项标签3

    mapper 将sql映射注册到全局配置中,这个我们在上一章已经使用过了, resource 这个属性是用来引用类路径下的sql映射文件 url 这个属性是用来引用网络路径或磁盘路径下的sql映射文件 ...

  2. 你不知道的JavaScript——this词法

    https://www.cnblogs.com/hutaoer/p/3423782.htmlhttps://www.cnblogs.com/vicky-li/p/8669549.htmlhttps:/ ...

  3. python raise

    当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常.一旦执行了raise语句,raise后面的语句将不能执行.   演示raise用法 try: s = None if s ...

  4. python之路--MySQl单表查询

    一.  关键字的执行优先级(重点) from where group by having # 使用是要放在group by 后面而且前面必须有group by select distinct # 去重 ...

  5. django rest framework权限和认证

    Django rest framework之权限 一.Authentication用户认证配置 1.四种验证及官网描述: BasicAuthentication 此身份验证方案使用HTTP基本身份验证 ...

  6. 集合之TreeMap(含JDK1.8源码分析)

    一.前言 前面所说的hashMap和linkedHashMap都不具备统计的功能,或者说它们的统计性能的时间复杂度都不是很好,要想对两者进行统计,需要遍历所有的entry,时间复杂度比较高,此时,我们 ...

  7. Python学习之路—————day04

    今日内容: 1. 循环语句 1.1 if判断 1.2 while循环 1.3 for循环 一.if判断 语法一: if 条件 代码块1 代码块2 代码块3 # 例: sex='female' age= ...

  8. Modification Default Identity Table

    Step 1. Open IdentityModel.cs to add following code. protected override void OnModelCreating(DbModel ...

  9. Civil 3D 二次开发 创建AutoCAD对象—— 00 ——

    不积跬步无以至千里,不积小流无以成江海.虽然创建一条直线.添加一个图层这样的小程序没有什么实际意义(内部命令很简单就可以完成),但对于初学二次开发的您来说,这可是一大步,这一步跨出去,您就跨进了二次开 ...

  10. 【题解】K乘积

    题目描述 有N个数,每个数的范围是[-50,50],现在你要从这N个数中选出K个,使得这K个数的乘积最大. 输入格式 第一行,N和K. 1 <= N <= 50.  1 <= K & ...