HDU 5652 India and China Origins 二分+搜索
2016-03-30 11:20
405 查看
题意:一个矩阵,黑点不能走,白点能走,有q步,每一步就是把一个白点变成黑点,如果需要k步,则是q的前k个都变成黑点,问最小的步数使得第一行和最后一行不联通。
想法:因为是前k个都变,如果不成功那么还需要更多的黑点,显然满足线性关系,那么这里就可以运用二分去枚举k值,对于这个k值改变地图的状态,然后把第一行的每一个点都搜一遍,如果都无法到达最后一行,表示此k值行的通。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
struct loc
{
int x,y;
}Q[250000+100];
struct node
{
int x,y;
};
int dir[4][2]={1,0,0,1,0,-1,-1,0};
int n,m,qnum;
char map[505][505],mapd[505][505];
bool bfs()
{
queue<node>q;
int vis[505][505];
node head,nxt;
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
{
if(map[0][i]=='1') continue;
while(!q.empty()) q.pop();
head.x=0;head.y=i;
vis[head.x][head.y]=i+1;
q.push(head);
while(!q.empty())
{
head=q.front();
q.pop();
if(head.x==n-1)
{
return false;
}
for(int k=0;k<4;k++)
{
nxt=head;
nxt.x+=dir[k][0];
nxt.y+=dir[k][1];
if(nxt.x<0||nxt.x>=n||nxt.y<0||nxt.y>=m) continue;
if(map[nxt.x][nxt.y]=='1') continue;
if(vis[nxt.x][nxt.y]!=i+1)
{
vis[nxt.x][nxt.y]=i+1;
q.push(nxt);
}
}
}
}
return true;
}
void build_map(int mid)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
map[i][j]=mapd[i][j];
}
}
for(int i=1;i<=mid;i++)
{
map[Q[i].x][Q[i].y]='1';
}
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",map[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
mapd[i][j]=map[i][j];
}
}
scanf("%d",&qnum);
for(int i=1;i<=qnum;i++)
{
scanf("%d%d",&Q[i].x,&Q[i].y);
}
build_map(0);
if(bfs())
{
printf("0\n");
continue;
}
int lft=0,rht=qnum;
int ans;
while(lft<=rht)
{
int mid=(lft+rht)/2;
build_map(mid);
if(bfs())
{
ans=mid;
rht=mid-1;
}
else lft=mid+1;
}
if(rht==qnum) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
想法:因为是前k个都变,如果不成功那么还需要更多的黑点,显然满足线性关系,那么这里就可以运用二分去枚举k值,对于这个k值改变地图的状态,然后把第一行的每一个点都搜一遍,如果都无法到达最后一行,表示此k值行的通。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
struct loc
{
int x,y;
}Q[250000+100];
struct node
{
int x,y;
};
int dir[4][2]={1,0,0,1,0,-1,-1,0};
int n,m,qnum;
char map[505][505],mapd[505][505];
bool bfs()
{
queue<node>q;
int vis[505][505];
node head,nxt;
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
{
if(map[0][i]=='1') continue;
while(!q.empty()) q.pop();
head.x=0;head.y=i;
vis[head.x][head.y]=i+1;
q.push(head);
while(!q.empty())
{
head=q.front();
q.pop();
if(head.x==n-1)
{
return false;
}
for(int k=0;k<4;k++)
{
nxt=head;
nxt.x+=dir[k][0];
nxt.y+=dir[k][1];
if(nxt.x<0||nxt.x>=n||nxt.y<0||nxt.y>=m) continue;
if(map[nxt.x][nxt.y]=='1') continue;
if(vis[nxt.x][nxt.y]!=i+1)
{
vis[nxt.x][nxt.y]=i+1;
q.push(nxt);
}
}
}
}
return true;
}
void build_map(int mid)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
map[i][j]=mapd[i][j];
}
}
for(int i=1;i<=mid;i++)
{
map[Q[i].x][Q[i].y]='1';
}
}
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",map[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
mapd[i][j]=map[i][j];
}
}
scanf("%d",&qnum);
for(int i=1;i<=qnum;i++)
{
scanf("%d%d",&Q[i].x,&Q[i].y);
}
build_map(0);
if(bfs())
{
printf("0\n");
continue;
}
int lft=0,rht=qnum;
int ans;
while(lft<=rht)
{
int mid=(lft+rht)/2;
build_map(mid);
if(bfs())
{
ans=mid;
rht=mid-1;
}
else lft=mid+1;
}
if(rht==qnum) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
相关文章推荐
- 0005--jcf(jdk1.7)-HashMap源码
- iOS UITextField或UITextView的内容是否为空
- 树状数组
- Masonry介绍与使用实践:快速上手Autolayout
- ISO/OSI 7层模型理解
- Linux 守护进程的启动方法
- wsdl4j 解析 wsdl
- jQuery 效果 - 淡入淡出
- linux tomcat 绑定域名
- 26字母转换成数字,26进制,a为1,aa为27,ab为28
- 入门(一)
- 前端工程师必备的PS技能——切图篇
- xib系列---基本 UI 控件详解 (UISegmentedControl | UIImageView | UIProgressView | UISlider | UIAlertView )
- Xcode 7 更新
- Xcode 7 更新
- HiveServer2 Clients
- Git 搭建私有仓库
- 【dfs+染色】【HDOJ】5652 India and China Origins
- Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
- Linux系统下创建任务,对指定目录文件进行自动压缩存档