您的位置:首页 > 其它

hdu 5334 多校(4)

2015-08-04 15:22 274 查看
题意是给你一个n*m的有0 1组成的矩阵    起点为坐上角  终点为右下角  从起点走到终点组成的一个二进制数最小;

思路:

1. 如果起点为零   则找到与起点相邻的联通0  的点 找到距离终点最近的一些点    然后找到最小的二进制数(建议用 bfs)

2.起点不为0  则直接从起点开始找最小的二进制数  具体找法为:

把下一步的点走找出来   如果其中有0的点 则不用走位1的点 把为零的加入队列 如果没有  则把所有的都加入队列   走的时候只用走右边和下边   想想为什么(2^ n肯定大于  2^(n-1)+.....2^0   说明长度越短越小)注意走过的点不能再走了(RE了好久) 具体实现我是用了一个优先队列(找到距离最小且为0 的起点) 一个普通队列  在跑起点时候 和对每个起点找到最小路径的时候。。。。。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;

char map[2100][2100];
int dir[4][2]={0,1,0,-1,1,0,-1,0};
int mark[2010][2010];
int n,m;
int path[3100];
struct node
{
int x,y;
}a,b;
struct Node
{
int x,y,dis;
bool operator < (const Node& g) const
{
return dis>g.dis;
}
}a1,b1;
priority_queue<Node>Q;
int bfs1(int x,int y)//找到所有起点
{
int flash=0;
a.x=x;
a.y=y;
a1.x=x;
a1.y=y;
a1.dis=n-x+m-y-1;

Q.push(a1);
queue<node>q;
memset(mark,0,sizeof(mark));
if(map[a.x][a.y]=='0') q.push(a);
mark[a.x][a.y]=1;
while(!q.empty())
{
b=q.front();
q.pop();
for(int i=0;i<4;i++)
{
a.x=b.x+dir[i][0];
a.y=b.y+dir[i][1];
if(a.x<0||a.x>=n||a.y<0||a.y>=m) continue;
if(mark[a.x][a.y]==0&&map[a.x][a.y]=='0')
{
mark[a.x][a.y]=1;
q.push(a);
if(a.x==n-1&&a.y==m-1) flash=1;
a1.x=a.x;
a1.y=a.y;
a1.dis=n+m-a.x-a.y-1;
Q.push(a1);
}
}
}
if(flash) return 1;
return 0;
}
int bfs2(int x,int y,int dis)//对每个起点  找到最小路径
{
int route[3100];
int leap[3100][3];
memset(mark,0,sizeof(mark));//开始少了这个标记走过的  re了好久
queue<node>qq;
a.x=x;
a.y=y;
qq.push(a);
int flash,j=0;
route[++j]=map[a.x][a.y]-'0';
int k;
while(1)//对每层的情况
{
k=0;
flash=0;
while(!qq.empty())
{
b=qq.front();
qq.pop();

if(b.x+1<n&&mark[b.x+1][b.y]==0)
{
mark[b.x+1][b.y]=1;
leap[++k][1]=b.x+1;
leap[k][2]=b.y;
if(map[b.x+1][b.y]=='0') flash=1;
}
if(b.y+1<m&&mark[b.x][b.y+1]==0)
{
mark[b.x][b.y+1]=1;
leap[++k][1]=b.x;
leap[k][2]=b.y+1;
if(map[b.x][b.y+1]=='0') flash=1;
}
}
if(k==0) break;
if(flash) route[++j]=0;
else route[++j]=1;
for(int i=1;i<=k;i++)
{
a.x=leap[i][1];
a.y=leap[i][2];
if(flash==0)
{
qq.push(a);
}
else
{
if(map[a.x][a.y]=='0') qq.push(a);
}
}
}
flash=0;
for(int i=1;i<=j;i++)
{
if(flash) path[i]=route[i];
else
{
if(route[i]<path[i])
{
path[i]=route[i];
flash=1;
}
}
}
return 0;
}
int main()
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%s",map[i]);
if(n==1&&m==1) {printf("%c\n",map[0][0]);continue;}

while(!Q.empty())
{
a1=Q.top();
Q.pop();
}

int d=bfs1(0,0);
if(d==1) {printf("0\n");continue;}
for(i=0;i<=2010;i++)
path[i]=1;

b1=Q.top();
Q.pop();
int Min=b1.dis;
bfs2(b1.x,b1.y,b1.dis);

while(!Q.empty())
{
b1=Q.top();
Q.pop();
if(b1.dis>Min) break;
bfs2(b1.x,b1.y,b1.dis);
}
if(path[1]==0) i=2;
else i=1;
for(;i<=Min;i++)
printf("%d",path[i]);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  搜索