[TCO2013]Block3Checkers
题意:一个网格上有一些障碍和$3$个在网格边界上的棋子,你要添加一些障碍使得没有两个棋子四连通,问最少添加多少个障碍
官方题解——一张图教你做人...

三个棋子将网格边界分成三段,添加障碍后网格中一定存在一个点使得它可以到这三段(只走障碍的路径,八连通)
所以找出这三段后分别以它们为起点跑最短路即可,经过障碍权值为$0$,经过空地权值为$1$
#include<stdio.h>
#include<queue>
#include<string.h>
#include<vector>
#include<string>
using namespace std;
int h[410],nex[7010],to[7010],v[7010],M;
void add(int a,int b,int c){
M++;
to[M]=b;
v[M]=c;
nex[M]=h[a];
h[a]=M;
}
int dis[410];
struct pr{
int x,d;
pr(int u=0){x=u;d=dis[u];}
}t;
bool operator<(pr a,pr b){return a.d>b.d;}
priority_queue<pr>q;
void dijk(int x){
int i;
memset(dis,63,sizeof(dis));
dis[x]=0;
q.push(x);
while(!q.empty()){
t=q.top();
q.pop();
x=t.x;
if(t.d!=dis[x])continue;
for(i=h[x];i;i=nex[i]){
if(dis[x]+v[i]<dis[to[i]]){
dis[to[i]]=dis[x]+v[i];
q.push(to[i]);
}
}
}
}
const int g4[4][2]={{0,1},{0,-1},{1,0},{-1,0}},g8[8][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int d[3][410],n,m;
vector<string>mp;
bool ok(int x,int y){
return 0<=x&&x<n&&0<=y&&y<m;
}
bool edge(int x,int y){
return ok(x,y)&&(x==0||x==n-1||y==0||y==m-1);
}
void dfs(int fx,int fy,int x,int y,int s){
int i,tx,ty;
if(mp[x][y]=='A')return;
add(s,x*m+y+1,0);
add(x*m+y+1,s,mp[x][y]=='.');
for(i=0;i<4;i++){
tx=x+g4[i][0];
ty=y+g4[i][1];
if((tx!=fx||ty!=fy)&&edge(tx,ty))dfs(x,y,tx,ty,s);
}
}
class Block3Checkers{
public:
int blockThem(vector<string>mp){
int i,j,k,x,y,f,s[3],ans;
::mp=mp;
n=mp.size();
m=mp[0].length();
s[0]=n*m+1;
s[1]=n*m+2;
s[2]=n*m+3;
f=0;
for(i=0;i<m;i++){
if(mp[0][i]=='A'){
if((i&&mp[0][i-1]=='A')||(i<m-1&&mp[0][i+1]=='A')||mp[1][i]=='A')return 100;
if(i==0)
dfs(0,0,1,0,s[f]);
else
dfs(0,i,0,i-1,s[f]);
f++;
}
if(mp[n-1][i]=='A'){
if((i&&mp[n-1][i-1]=='A')||(i<m-1&&mp[n-1][i+1]=='A')||mp[n-2][i]=='A')return 100;
if(i==m-1)
dfs(n-1,m-1,n-2,m-1,s[f]);
else
dfs(n-1,i,n-1,i+1,s[f]);
f++;
}
}
for(i=1;i<n-1;i++){
if(mp[i][0]=='A'){
if(mp[i-1][0]=='A'||mp[i+1][0]=='A')return 100;
dfs(i,0,i+1,0,s[f]);
f++;
}
if(mp[i][m-1]=='A'){
if(mp[i-1][m-1]=='A'||mp[i+1][m-1]=='A')return 100;
dfs(i,m-1,i-1,m-1,s[f]);
f++;
}
}
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(mp[i][j]!='A'){
for(k=0;k<8;k++){
x=i+g8[k][0];
y=j+g8[k][1];
if(ok(x,y)&&mp[x][y]!='A')add(i*m+j+1,x*m+y+1,mp[i][j]=='.');
}
}
}
}
for(i=0;i<3;i++){
dijk(s[i]);
memcpy(d[i],dis,sizeof(dis));
}
ans=n*m;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
if(mp[i][j]!='A'){
x=i*m+j+1;
ans=min(ans,d[0][x]+d[1][x]+d[2][x]+(mp[i][j]=='.'));
}
}
}
return ans;
}
};
/*
int main(){
vector<string>vt;
char s[30];
Block3Checkers cl;
while(~scanf("%s",s))vt.push_back(s);
printf("%d",cl.blockThem(vt));
}
*/
[TCO2013]Block3Checkers的更多相关文章
- [TCO2013]TrickyInequality
$\newcommand{stirf}[2]{{{#1}\brack{#2}}}$$\newcommand{stirs}[2]{{{#1}\brace{#2}}}$题意:$\sum\limits_{i ...
- [TCO2013]LitPanels
题意:一个$n\times m$的无色网格,你可以在其中选择两个$x\times y$的子矩形并在其中将其中任意的格子涂上颜色,问最终能得到多少种不同的网格 做这题会用到一个概念叫包围盒(boundi ...
- [TCO2013]DirectionBoard
题意:给一个网格,每个格子有一个方向表示在这个格子上要往哪个方向走,你可以改变某些格子的方向,问最少多少次操作使得从任意格子出发都能回到这个格子 woc这都不会我还是回家种田去吧... 题目的要求是改 ...
随机推荐
- IT培训班123
最近20年,IT行业一直处于上升期,程序员的工资越来越高了,年薪几十万的程序员大有人在.根据国家统计局发布的2016年各行业平均工资报表,程序员已经是工资最高的一个群体,超过了金融行业. IT行业的火 ...
- react-native中使用Echarts,自己使用WebView封装Echarts经验
1.工作中遇到的问题 我们在使用react-native肯定遇到过各种奇葩的问题,比如引入Echarts时候莫名报错,但是Echarts官网明显告诉我们可以懒加载的,这是因为基本上js大部分原生的组件 ...
- 用例图(Use Case Diagram)
用例图(Use Case Diagram) 执行者/参与者(Actor): 表示与您的应用程序或系统进行交互的用户.组织或外部系统.用一个小人表示. 用例(Use Case): 即系统具有的功能,在用 ...
- Python爬虫—破解JS加密的Cookie
前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站.上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521.抱着帮人解决问题的心态去跑了一遍代码.发现果真是这样. ...
- socket 编程 TCP 实现简单聊天功能【转】
转自:http://blog.csdn.net/liujia2100/article/details/9006479 版权声明:本文为博主原创文章,未经博主允许不得转载. 各个主要函数的功能: .so ...
- php文件读取的问题
PHP字符编码问题 首先说下字符编码问题,当我们给定路径后如果路径中包含中文,可能会出现问题,打印到屏幕则显示没问题, 但是读取文件会报错:readfile(E:/素玄文件/app历史版本/素玄ERP ...
- java数组面试题
一维数组可以写成:int[ ]x 或者int x[ ]: 二维数组可以写成:int[ ] y [ ] 或者int y[ ][ ] 或者int [ ][ ]y 面试题如下: 声明数组int[ ...
- [ python ] 项目:haproxy配置文件增删改查
1. 开发要求 实现对 haproxy.cfg 增删改查操作 2. 程序介绍 # 作者:hkey # 博客地址:https://www.cnblogs.com/hukey/p/9288279.html ...
- LeetCode解题报告—— 4Sum & Remove Nth Node From End of List & Generate Parentheses
1. 4Sum Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + ...
- PHP PDO类
<?php //数据库连接类,不建议直接使用DB,而是对DB封装一层 //这个类不会被污染,不会被直接调用 class DB { //pdo对象 private $_pdo = null; // ...