搜索

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为出发点,找出“距离”最近的朋友。

代码
&nbsp;
#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;
}

 

posted on 2010-11-13 09:48  CrazyAC  阅读(183)  评论(0编辑  收藏  举报