[SRM570]TheTiles
题意:给一个$n\times m$的网格,对这个网格黑白染色,左上角为黑色。现在要用一些大小为$3$的L型图形覆盖这个网格,要求不能重复覆盖同一个格子,不能覆盖到障碍,L型可以进行旋转,但转角处格子必须为黑色,求最多能覆盖多少个L型图形
人生第一次上TC做题2333,最近机房网络不太稳定,lantern也经常崩,所以做这道题用了十几分钟才成功提交一次==
无论怎么旋转L型,两个白格必定不在同一行
所以$S$向奇数行白格连边,奇数行白格向相邻黑格连边,黑格向相邻偶数行白格连边,偶数行白格向$T$连边,这样跑最大流就对应着许多L型图形
为了保证每个格子最多被用一次,拆点连边限制流量即可
#include<stdio.h> #include<string.h> #include<vector> #include<string> using namespace std; const int inf=2147483647; int min(int a,int b){return a<b?a:b;} int h[5010],cur[5010],nex[30010],to[30010],cap[30010],dis[5010],q[5010],M=1,S,T; void add(int a,int b,int c){ M++; to[M]=b; cap[M]=c; nex[M]=h[a]; h[a]=M; M++; to[M]=a; cap[M]=0; nex[M]=h[b]; h[b]=M; } bool bfs(){ int head,tail,x,i; memset(dis,-1,sizeof(dis)); head=tail=1; q[1]=S; dis[S]=0; while(head<=tail){ x=q[head]; head++; for(i=h[x];i;i=nex[i]){ if(cap[i]&&dis[to[i]]==-1){ dis[to[i]]=dis[x]+1; if(to[i]==T)return 1; tail++; q[tail]=to[i]; } } } return 0; } int dfs(int x,int flow){ if(x==T)return flow; int i,f; for(i=cur[x];i;i=nex[i]){ if(cap[i]&&dis[to[i]]==dis[x]+1){ f=dfs(to[i],min(flow,cap[i])); if(f){ cap[i]-=f; cap[i^1]+=f; if(cap[i])cur[x]=i; return f; } } } dis[x]=-1; return 0; } int dicnic(){ int ans=0,tmp; while(bfs()){ memcpy(cur,h,sizeof(h)); while(1){ tmp=dfs(S,inf); if(tmp==0)break; ans+=tmp; } } return ans; } const int gx[4]={1,-1,0,0},gy[4]={0,0,1,-1}; char s[50][50]; int n,m; int p(int x,int y){return(x-1)*m+y;} int in(int x,int y){return p(x,y)*2-1;} int ou(int x,int y){return p(x,y)<<1;} int col(int x,int y){ if(~(x+y)&1)return 2; return(~x&1)*2+1; } bool ok(int x,int y){return 0<x&&x<=n&&0<y&&y<=m&&s[x][y]=='.';} class TheTilesDivOne{ public: int find(vector<string>board){ int i,j,k,x,y; n=board.size(); m=board[0].length(); for(i=1;i<=n;i++)strcpy(s[i]+1,board[i-1].c_str()); S=n*m*2+1; T=n*m*2+2; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(s[i][j]=='.'){ add(in(i,j),ou(i,j),1); if(col(i,j)==1)add(S,in(i,j),1); if(col(i,j)==3) add(ou(i,j),T,1); else{ for(k=0;k<4;k++){ x=i+gx[k]; y=j+gy[k]; if(ok(x,y)&&col(i,j)+1==col(x,y))add(ou(i,j),in(x,y),1); } } } } } return dicnic(); } }; /* vector<string>v; TheTilesDivOne test; char str[50]; int main(){ int n,m,i; scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%s",str); v.push_back(str); } printf("%d",test.find(v)); } */
辣鸡TC连warning都不给过,差评==
[SRM570]TheTiles的更多相关文章
- Topcoder SRM570 900 CurvyonRails
题意:给定一个网格,一些格子是障碍不用管,剩余的格子是城市,你可以修建铁路,铁路的形状可以是直的或者弯的,也就是说可以以这个点为节点连接它四联通的其中两个方块.要求用一个或多个环来覆盖所有城市.对于有 ...
- Topcoder SRM570 D1L3 CurvyonRails
几个样例: 5 5wCCwwwCC....w......www..wReturns: 0 3 3C.w....C.Returns: 1 21 20CC..CCCw.CwC..CC.w.CC.CCCwC ...
随机推荐
- [bzoj 2844]线性基+高斯消元
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 又用到线性基+高斯消元的套路题了,因为经过高斯消元以后的线性基有非常好的序关系,所以 ...
- Codeforces Round #525 (Div. 2)D. Ehab and another another xor problem
D. Ehab and another another xor problem 题目链接:https://codeforces.com/contest/1088/problem/D Descripti ...
- Java之戳中痛点 - (4)i++ 和 ++i 探究原理
先看一个例子: package com.test; public class AutoIncrement { public static void main(String[] args) { int ...
- P值
https://baike.baidu.com/item/P%E5%80%BC/7083622?fr=aladdin https://baijiahao.baidu.com/s?id=15960976 ...
- Windows下安装Mycat-web
Mycat-web是基于Mycat的一个性能监控工具,如:sql性能监控等. 在安装Mycat-web之前需要先安装Zookeeper: 可参考: http://blog.csdn.net/tlk20 ...
- AngularJs学习——实现数据绑定的三种方式
三种方式: 方式一:<h5>{{msg}}</h5> 此方式在页面刷新的时候会闪现{{}} 方式二:<h5 ng-bind="msg">< ...
- Web.xml过滤器配置及执行顺序概念
第一个过滤器 @Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain ch ...
- 【BZOJ】1782: [Usaco2010 Feb]slowdown 慢慢游
[算法]DFS序+树状数组 [题解]题意相当于统计前i-1个点在第i个点的祖先的个数,显然可以用dfs维护,用树状数组差分维护前缀和. 出栈不新加节点就要注意左闭右开,即in[a[i]]处+1,ou[ ...
- 浅谈 原生javaScript && react 实现全局触摸按钮(附带对addeventlistener的了解)
1.采用原生javaACript 实现全局触摸按钮 首先在控制台输出,观察事件有哪些关于触摸的字段可以使用,然后拿这些字段的数据开始来写方法. 因为要做的是全局触摸按钮,我需要拿到的是按钮时时的坐标位 ...
- mongodb的集合操作
MongoDB 创建集合 1.手动创建: 语法格式: db.createCollection(name, options) 参数说明: name: 要创建的集合名称 options: 可选参数, 指定 ...