HDU 5335(2015 ACM多校训练第四场1009)
2015-08-01 16:12
465 查看
Walk Out
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2469 Accepted Submission(s): 485
Problem Description
In an n∗m maze,
the right-bottom corner is the exit (position (n,m) is
the exit). In every position of this maze, there is either a 0 or
a 1 written
on it.
An explorer gets lost in this grid. His position now is (1,1),
and he wants to go to the exit. Since to arrive at the exit is easy for him, he wants to do something more difficult. At first, he'll write down the number on position (1,1).
Every time, he could make a move to one adjacent position (two positions are adjacent if and only if they share an edge). While walking, he will write down the number on the position he's on to the end of his number. When finished, he will get a binary number.
Please determine the minimum value of this number in binary system.
Input
The first line of the input is a single integer T (T=10),
indicating the number of testcases.
For each testcase, the first line contains two integers n and m (1≤n,m≤1000).
The i-th
line of the next n lines
contains one 01 string of length m,
which representsi-th
row of the maze.
Output
For each testcase, print the answer in binary system. Please eliminate all the preceding 0 unless
the answer itself is 0 (in
this case, print 0 instead).
Sample Input
2 2 2 11 11 3 3 001 111 101
Sample Output
111 101
Author
XJZX
题意:
给一个n*m的图。图上每个位置为0或者1。
有一个人在该图中走。每走一个位置把该位置的数字记录下来。
问从这个人从图的左上角(0,0)走到图的右下角(n-1,m-1)形成的二进制数最小是多少,输出这个二进制(该二进制的前导0不必输出)。
思路:
初次看本题时以为是一个从左上角向右下角的dp,但是仔细想想就会有问题,dp的状态转移情况不一定是向右或者是向下的。
例如:
5 5
01111
01000
01010
01010
00011
答案是:1
后来想想应该是一个向下或向右的贪心。但是这样还是无法处理上述的情况,最后只能对这种情况进行特殊处理;
当起始点为0时先把所有与起始点相邻的0点跑出来,放进优先队列里面,然后取其中横坐标+纵坐标最大的值(横坐标+纵坐标越大,离(n-1,m-1)的距离越近,二进制位数越小,二进制值越小),当然如果这样的值有多个则都取出来,每个都进行向下向右的BFS广搜,而且广搜的同时,再与终点距离相同的点中,优先选择所有的0点,一旦存在0点则放弃所有1点。
至于这些如何实现。。。。。。。。。。。。。。不得不承认自己还是太弱了。竟然需要用两个优先队列,两个普通队列来实现。
后来看了别人短小精悍的代码后更是感觉自己的代码无法直视O__O "…
虽然这样写起来思路非常清晰,但是代码还是太冗长了 (>﹏<)
#include <iostream> #include <stdlib.h> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int maxx = 1000 + 10; int n, m; char str[maxx][maxx]; char ans[maxx*maxx]; char ans_str[maxx*maxx]; bool vis[maxx][maxx]; int kjudge; int dir1[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; struct node1{ int x; int y; bool operator < (const node1 & a)const{ return a.x+a.y > x+y; } }; priority_queue<node1> pp1; queue<node1> p1; int dir2[2][2] = {{1,0},{0,1}}; struct node2{ int x; int y; int num; int id; bool operator < (const node2& a) const { if(a.num == num) return a.id < id; return a.num < num; } }; priority_queue<node2> pp2; queue<node2> p2; bool ok(int x,int y){ if(x<0||x>=n) return false; if(y<0||y>=m) return false; return true; } bool ok1(int x,int y){ if(ok(x,y)&&str[x][y] == '0'){ return true; } return false; } bool ok2(int x,int y){ if(ok(x,y)&&vis[x][y] == false){ return true; } return false; } void output(int len){ int i = 0; if(ans_str[0] == '9') i++; for(; i < len; ++i){ printf("%c",ans_str[i]); } printf("\n"); } int bfs2(int x,int y){ node2 k; if(str[n-1][m-1] == '9'){ printf("0\n"); return -1; } if(x == n-1 &&y == m-1){ printf("%c\n",str[n-1][m-1]); return -1; } memset(vis,false,sizeof(vis)); memset(ans,'_',sizeof(ans)); k.x = x; k.y = y; k.num = 1; ans[0] = str[k.x][k.y]; k.id = str[k.x][k.y] - '0'; vis[x][y] = true; pp2.push(k); int now = k.num; int judge = k.id; while(!pp2.empty()){ node2 q = pp2.top(); pp2.pop(); if(now != q.num){ now = q.num; judge = q.id; } if(judge == q.id){ for(int i = 0;i < 2; ++i){ int dx = dir2[i][0]+q.x; int dy = dir2[i][1]+q.y; if(dx == n-1 && dy == m-1){ ans[q.num] = str[dx][dy]; if(!kjudge){ for(int j = 0;j <= q.num; ++j){ ans_str[j] = ans[j]; } }else{ int mj = 0; for(int j = 0;j <= q.num; ++j){ if(ans_str[j] > ans[j]){ mj = 1; break; } } if(mj){ for(int j = 0;j <= q.num; ++j){ ans_str[j] = ans[j]; } } } while(!pp2.empty()) pp2.pop(); return q.num+1; } if(ok2(dx,dy)){ if(ans[q.num] == '_')ans[q.num] = str[dx][dy]; else ans[q.num] = min(ans[q.num],str[dx][dy]); vis[dx][dy] = true; node2 temp; temp.id = str[dx][dy] - '0'; temp.x = dx; temp.y = dy; temp.num = q.num+1; pp2.push(temp); } } } } } void bfs1(){ ///找起点位置 node1 k; k.x = 0; k.y = 0; kjudge = 0; int klen = -1; if(str[0][0] == '0') { p1.push(k); str[0][0] = '9'; while(!p1.empty()){ node1 q = p1.front(); pp1.push(q); p1.pop(); for(int i = 0;i < 4; ++i){ int dx = dir1[i][0] + q.x; int dy = dir1[i][1] + q.y; if(ok1(dx,dy)){ node1 temp; temp.x = dx; temp.y = dy; str[dx][dy] = '9'; p1.push(temp); } } } int judge = pp1.top().x + pp1.top().y; while(!pp1.empty()){ node1 temp = pp1.top(); if(judge == temp.x+temp.y){ klen = bfs2(temp.x,temp.y); } pp1.pop(); } }else{ klen = bfs2(0,0); } if(klen != -1)output(klen); } int main(){ int T; cin>>T; while(T--){ scanf("%d%d",&n,&m); for(int i = 0;i < n; ++i){ scanf("%s",str[i]); } bfs1(); } return 0; }
如有BUG,请大家务必指出,不胜感激~
联系方式:274489985@qq.com
相关文章推荐
- hdu-4970--Killing Monsters--数组的巧妙
- java技术经理面试题
- C语言编程入门——数组(上)
- Tom and paper
- Servlet实现文件上传,可多文件上传
- nyoj 九的余数
- Scala入门到精通——第十四节 Case Class与模式匹配(一)
- ise错误Cannot access memory * directly;Cannot assign memory * directly
- 最近点对问题(欧几里得算法)
- 静态初始化与构造函数,先执行静态初始化,再执行构造函数,总是先执行父类的,再执行子类的
- PsCreateSystemThread
- hihoCoder 1051 补提交卡
- 系统之家一键重装工具怎么使用?系统之家一键重装工具安装win8图文教程
- solr httpclient请求方式 原子更新索引
- [python]字符串的排序
- Android源码大放送(实战开发必备)
- java泛型之基础
- HDU 2435 There is a war Dinic 最小割
- WCF HTTP 错误 404.3 - Not Found(由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。)
- 初等数论总结(填坑)