您的位置:首页 > 大数据 > 人工智能

hdu 5335 Walk Out 2015 Multi-University Training Contest 4

2015-08-25 13:05 489 查看
因为前缀0对答案没有影响,所以可以先BFS找出起点经过0可以到达的1,这些1作为新的起点。二进制数位数越少那么值越小,所以应该找距离(n,m)最近,即n-x+m-y+1最小的点(可能有多个)。并且搜索时只能沿下或右方向搜索。因为如果向左方或上方搜索,二进制数的总位数必然增加,且最高位是1,所以值只会增大。

然后我卡在了是否搜索到了(n,m)就要输出。比如一下这种case,

100

000

011

如果先搜下再搜右,路径是10011,如果先搜右再搜下,路径是10001。所以不能先到达终点就输出结果,当然也可以全部存起来最后在比较。><

有一种trick是如果BFS的某一层里有0,那么这一层的1都不搜索。而是否有0可以在扩展子节点的过程中进行判断。因为BFS的层数可以对应到二进制数的某一位,这样就保证了某一位优先选0。

最后注意如果在找起点的BFS过程中扩展到了(n,m),那么说明可以直接经过一系列0到达终点,这种case需要特判。否则再从其他1开始搜索会WA。

臣妾先是忘记标记vis数组重复扩点导致MLE,然后忘了初始化数组导致WA=。=

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<vector>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<queue>
#include<ctype.h>
#include<map>
#include<time.h>
#include<bitset>
#include<set>
#include<list>
using namespace std;
//hdu 5335

const int maxn=1010;
const int INF=0x3f3f3f3f;
int T;
int n;
int m;
int dx[]={0,-1,0,1};
int dy[]={-1,0,1,0};
int mp[maxn][maxn];
bool vis[maxn][maxn];
int dis[maxn][maxn];
bool existzero[maxn];
vector<pair<int,int> >start;
pair<int,int>pre[maxn][maxn];
int minlen;
bool flgnone;
void bfs_start()
{
minlen=INF;
if(mp[1][1]==1)
{
start.push_back(make_pair(1,1));
minlen=n+m-1;
return;
}
queue<pair<int,int> >que;
que.push(make_pair(1,1));
vis[1][1]=true;
pair<int,int>now;
while(!que.empty())
{
now=que.front();
que.pop();
if(now.first==n&&now.second==m)//we need to judge it here not in the loop of expansion process
{//if there is only one point which is zero.
flgnone=true;
return;
}
for(int i=0;i<4;i++)
{
int x=now.first+dx[i];
int y=now.second+dy[i];
if(x<1||x>n||y<1||y>m) continue;
if(vis[x][y]) continue;
if(mp[x][y]==0)
{
que.push(make_pair(x,y));
vis[x][y]=true;
}
else
{
start.push_back(make_pair(x,y));
vis[x][y]=true;
int tmp=n+m-x-y+1;
if(minlen>tmp)
{
minlen=tmp;
}
}
}
}
return;
}
void print(int x,int y)
{
if(pre[x][y].first==0&&pre[x][y].second==0)
{
printf("%d",mp[x][y]);
return;
}
print(pre[x][y].first,pre[x][y].second);
printf("%d",mp[x][y]);
}
void solve()
{
queue<pair<int,int> >que;//maybe there more than one start point
// cout<<start.size()<<endl;
for(int i=0;i<start.size();i++)
{
// cout<<start[i].first<<" "<<start[i].second<<endl;
int tmp=n+m-start[i].first-start[i].second+1;
if(minlen==tmp)
{
que.push(start[i]);
vis[start[i].first][start[i].second]=true;
pre[start[i].first][start[i].second]=make_pair(0,0);
dis[start[i].first][start[i].second]=1;
}
}
existzero[1]=0;
pair<int,int>now;
while(!que.empty())
{
now=que.front();
que.pop();
if(now.first==n&&now.second==m)
{
print(now.first,now.second);
return;
// if(pre[now.first][now.second].first!=0&&pre[now.first][now.second].second!=0)
// {
// print(now.first,now.second);
// return;
// }
}
if(existzero[dis[now.first][now.second]]==1&&mp[now.first][now.second]==1)
{
continue;
}
for(int i=2;i<4;i++)
{
int x=now.first+dx[i];
int y=now.second+dy[i];
if(x<1||x>n||y<1||y>m) continue;
if(vis[x][y]) continue;
que.push(make_pair(x,y));
pre[x][y]=now;
vis[x][y]=true;
dis[x][y]=dis[now.first][now.second]+1;
if(mp[x][y]==0)
{
existzero[dis[x][y]]=1;
}
}
}
return;
}
int main()
{
freopen("input.txt","r",stdin);
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
scanf("%d %d",&n,&m);
memset(vis,false,sizeof(vis));
memset(dis,0,sizeof(dis));
memset(mp,0,sizeof(mp));
memset(pre,0,sizeof(pre));
memset(existzero,0,sizeof(existzero));
start.clear();
flgnone=false;
char str[maxn];
for(int i=1;i<=n;i++)
{
scanf("%s",str+1);
for(int j=1;j<=m;j++)
{
mp[i][j]=str[j]-'0';
}
}
// cout<<n<<" nm "<<m<<endl;
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=m;j++)
// {
// cout<<mp[i][j]<<" ";
// }
// cout<<endl;
// }
// cout<<"ed1"<<endl;
bfs_start();
if(flgnone==true)
{
printf("0\n");
continue;
}
solve();
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: