搜索
1.hdoj 1728 逃离迷宫
这题本来用优先队列做的,WA很多次。 网上看到下面的解释:
举个例子,到达某个点的时候方向为向上或者向右的最少转弯次数都是4次
假如终点在向上的方向,那么总的最少转弯次数就是4次
但是开2维数组有可能造成记录的是向右的状态,因为同是4次。
那么这样到达终点就需要5次转弯了。
代码
#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
class pt{
public:
int x, y;
};
int dir[4][2] = {1, 0, 0, 1, 0, -1, -1, 0};
char mp[110][110];
int num[110][110];
int limit, sx, sy, ex, ey, n, m;
bool solve(){
pt p, q;
int i, t;
queue<pt> Q;
memset(num, -1, sizeof(num));
p.x = sx;
p.y = sy;
Q.push(p);
while(!Q.empty()){
p = Q.front();
Q.pop();
t = num[p.x][p.y] + 1;
if(t > limit) continue;
for(i=0; i<4; ++i){
q.x = p.x + dir[i][0];
q.y = p.y + dir[i][1];
while(q.x >= 0 && q.x < n && q.y >= 0 && q.y < m && mp[q.x][q.y]=='.'){
if(num[q.x][q.y] == -1 || num[q.x][q.y] >= t){
num[q.x][q.y] = t;
Q.push(q);
if(q.x == ex && q.y == ey) return 1;
}
q.x += dir[i][0];
q.y += dir[i][1];
}
}
}
return 0;
}
void init(){
int i;
scanf("%d %d", &n, &m);
for(i=0; i<n; ++i){
scanf("%s", mp[i]);
}
scanf("%d %d %d %d %d", &limit, &sy, &sx, &ey, &ex);
--sx; --sy;
--ex; --ey;
}
int main(){
// freopen("c:/aaa.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--){
init();
if(solve()) puts("yes");
else puts("no");
}
return 0;
}
2.hdoj 1242 Rescue
以Angel为出发点,找出“距离”最近的朋友。
代码
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#define inf 10000000
using namespace std;
class Node{
public:
int x, y, v;
};
bool operator>(Node a, Node b){
return a.v > b.v;
}
int n, m;
int sx, sy;
int dir[4][2] = {1, 0, 0, 1, 0, -1, -1, 0};
char mp[210][210];
int num[210][210];
void solve(){
int i, j, ans;
priority_queue<Node, vector<Node>, greater<Node> > Q;
int mark[210][210];
Node p, q;
memset(mark, 0, sizeof(mark));
memset(num, 0, sizeof(num));
p.x = sx;
p.y = sy;
p.v = 0;
Q.push(p);
mark[sx][sy] = 1;
while(!Q.empty()){
p = Q.top();
Q.pop();
for(i=0; i<4; ++i){
q.x = p.x + dir[i][0];
q.y = p.y + dir[i][1];
if(q.x < 0 || q.x >= n || q.y < 0 || q.y >= m) continue;
if( mp[q.x][q.y] == '#' || mark[q.x][q.y] ) continue;
q.v = p.v + 1;
if(mp[q.x][q.y] == 'x') ++q.v;
Q.push(q);
mark[q.x][q.y] = 1;
num[q.x][q.y] = q.v;
}
}
ans = inf;
for(i=0; i<n; ++i){
for(j=0; j<m; ++j){
if(mp[i][j] == 'r' && num[i][j] < ans && mark[i][j])
ans = num[i][j];
}
}
if(ans == inf) puts("Poor ANGEL has to stay in the prison all his life.");
else printf("%d\n", ans);
}
void init(){
int i, j;
for(i=0; i<n; ++i){
scanf("%s", mp[i]);
}
for(i=0; i<n; ++i){
for(j=0; j<m; ++j){
if(mp[i][j] == 'a'){
sx = i;
sy = j;
break;
}
}
}
}
int main(){
// freopen("c:/aaa.txt", "r", stdin);
while(scanf("%d %d", &n, &m)!=EOF){
init();
solve();
}
return 0;
}