A题 hdu1242
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1242
题目大意:Angel被关到监狱里,他的朋友们 'r '想要营救他,及找到Angel的位置 'a' 。监狱有墙 ‘#’ ,警卫‘x’,遇到警卫就杀死,多用一个单位时间,在监狱里可以向上走,向右走,向左走,向右走,问朋友到达Angel最短的时间。
要注意的是Angel的朋友不止一个,所以从Angel的位置开始找,找到离他最近的朋友的位置。
#include <bits/stdc++.h>
#include <queue>
using namespace std;
const int MAXN = 200 + 10;
vector<int> G[MAXN];
char str[MAXN][MAXN];
int vis[MAXN][MAXN];//标记是否走过
int n, m;
struct node {
int x, y;
int step;
friend bool operator < (node a, node b) {//重载运算符
return a.step > b.step;
}
};
int d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
//d[0][0]=1 d[0][1]=0
//d[1][0]=-1 d[1][1]=0
//d[2][0]=0 d[2][1]=1
//d[3][0]=0 d[3][1]=-1
void BFS(int x1, int y1, int x2, int y2) {
memset(vis, 0, sizeof(vis));
priority_queue<node> que;
node now, next;//now当前位置,next下一步
now.x = x1, now.y = y1, now.step = 0;//起点的位置赋给now
que.push(now);
vis[x1][y1] = 1;
int ans = -1;
while(!que.empty()) {//队列为空,说明到达终点
now = que.top();//访问最底端
que.pop();//移除最底端
if(now.x == x2 && now.y == y2) {//走到了终点
ans = now.step;
break;//break就是用来跳出本层for和while的,跟有没有if没有关系
}
//(1,0)右移,(-1,0)左移, (0,1)上移,(0,-1) 下移
for(int i = 0; i < 4; ++i) {//优先级:右,左,上,下
next.x = now.x + d[i][0];
next.y = now.y + d[i][1];
if(next.x < 0 || next.x >= n || next.y < 0 || next.y >= m) continue;
if(vis[next.x][next.y] == 1) continue;//已经走过
if(str[next.x][next.y] == '#') continue;//墙壁
if(str[next.x][next.y] == 'x') next.step = now.step + 2;//遇到护卫
else next.step = now.step + 1;// else包括两种情况下一步是'.' 或'r'
que.push(next);//此点入队列
vis[next.x][next.y] = 1;
}
}
if(ans == -1) puts("Poor ANGEL has to stay in the prison all his life.");//puts自带换行
else printf("%d\n", ans);
}
int main() {
int stx, sty,edx, edy;
while(scanf("%d %d", &n, &m) != EOF) {
for(int i = 0; i < n; ++i) scanf("%s", str[i]);//以字符串形式按行输入
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(str[i][j] == 'a') stx = i, sty = j;//起点 ,angle
if(str[i][j] == 'r') edx = i, edy = j;//终点 ,friends
}
}
BFS(stx, sty, edx, edy);
}
return 0;
}
补充
HDU1312 不知道终点
//BFS
#include <bits/stdc++.h>
#include <queue>
using namespace std;
char str[30][30];
int vis[30][30];//标记是否走过
int w, h;
struct node {
int x, y;
//int step;
};
int d[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//(1,0)右移,(-1,0)左移, (0,1)上移,(0,-1) 下移
void BFS(int x1, int y1) {
memset(vis, 0, sizeof(vis));
queue<node> que;
node now, next;
now.x = x1, now.y = y1;
que.push(now);
vis[x1][y1] = 1;
int ans=0 ;
while(!que.empty()) {//队列为空,说明到达终点
now = que.front();//访问最底端
ans++;
que.pop();//移除最底端
for(int i = 0; i < 4; ++i) {
next.x = now.x + d[i][0];
next.y = now.y + d[i][1];
if(next.x >= 0 && next.x < h && next.y >=0 && next.y < w && !vis[next.x][next.y] && str[next.x][next.y] != '#'){
que.push(next);//此点入队列
vis[next.x][next.y] = 1;
}
else continue;//不能用break
}
}
printf("%d\n", ans);
}
int main() {
int stx, sty;
while(scanf("%d %d", &w, &h) != EOF && (w||h)) {
memset(str, 0, sizeof(str));
for(int i = 0; i < h; ++i) scanf("%s", str[i]);//以字符串形式按行输入
for(int i = 0; i < h; ++i) {
for(int j = 0; j < w; ++j) {
if(str[i][j] == '@') stx = i, sty = j;//起点
}
}
BFS(stx, sty);
}
return 0;
}
//DFS
#include <bits/stdc++.h>
#include <queue>
using namespace std;
char str[30][30];
int vis[30][30];//标记是否走过
int w, h,ans;
bool check(int x,int y)
{
if(x >= 0 && x < h && y >=0 && y < w && !vis[x][y] && str[x][y] != '#')
return 1;
else
return 0;
}
int d[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//(1,0)右移,(-1,0)左移, (0,1)上移,(0,-1) 下移
void DFS(int x,int y){
if(!check(x,y))
return ;
else
{
ans++;
int newx,newy;
for(int i=0;i<4;i++)
{
vis[x][y] = 1;
newx = x + d[i][0];
newy = y + d[i][1];
DFS(newx,newy);
}
return ;
}
}
int main()
{
int stx, sty;
while(scanf("%d %d", &w, &h) != EOF && (w||h))
{
memset(str, 0, sizeof(str));
memset(vis, 0, sizeof(vis));
for(int i = 0; i < h; ++i)
scanf("%s", str[i]);//以字符串形式按行输入
for(int i = 0; i < h; ++i)
{
for(int j = 0; j < w; ++j)
{
if(str[i][j] == '@') stx = i, sty = j;//起点
}
}
ans=0;
DFS(stx,sty);
printf("%d\n", ans);
}
return 0;
}
B题 NYOJ284
题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=284
空格,河,铁墙,砖墙
你的任务是尽快得到奖金,假设没有敌人会打扰你。
你的坦克不能过河、过墙,可以射击砖墙。砖墙被射击后变空格,铁墙被射击不受影响。
你可以朝四个方向移动,射击方向是你的当前方向,砖墙被射击后变空格(只在本回合)
注意:砖墙(B)因为需要先打破再通过故算两次操作
输入:
M N(地图是M行,N列)
'Y' (you), 'T' (target目标地点), 'S' (steel wall), 'B' (brick wall), 'R' (river) and 'E' (empty space). Both 'Y' and 'T' appear only once.
AC
#include <bits/stdc++.h>
#include <queue>
using namespace std;
const int MAXN = 300 + 10;
vector<int> G[MAXN];
char str[MAXN][MAXN];
int vis[MAXN][MAXN];
int n, m;
struct node {
int x, y;
int step;
friend bool operator < (node a, node b) {
return a.step > b.step;
}
};
int d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
void BFS(int x1, int y1, int x2, int y2) {
memset(vis, 0, sizeof(vis));
priority_queue<node> que;
node e1, e2;
e1.x = x1, e1.y = y1, e1.step = 0;
que.push(e1);
vis[x1][y1] = 1;
int ans = -1;
while(!que.empty()) {
e1 = que.top();
que.pop();
if(e1.x == x2 && e1.y == y2) {
ans = e1.step;
break;
}
for(int i = 0; i < 4; ++i) {
e2.x = e1.x + d[i][0];
e2.y = e1.y + d[i][1];
if(e2.x < 0 || e2.x >= m || e2.y < 0 || e2.y >= n) continue;
if(vis[e2.x][e2.y] == 1) continue;
if(str[e2.x][e2.y] == 'R' || str[e2.x][e2.y] == 'S') continue;//River, Steel
if(str[e2.x][e2.y] == 'B') e2.step = e1.step + 2;//Brick
if(str[e2.x][e2.y] == 'E' || str[e2.x][e2.y] =='T') e2.step = e1.step + 1;
que.push(e2);
vis[e2.x][e2.y] = 1;
}
}
//if(ans == -1) puts("-1");
//else printf("%d\n", ans);
printf("%d\n", ans);
}
int main() {
int edx, edy, stx, sty;
while((scanf("%d %d", &m, &n) != EOF ) &&( m || n)) {
for(int i = 0; i < m; ++i) scanf("%s", str[i]);
for(int i = 0; i < m; ++i) {
for(int j = 0; j < n; ++j) {
if(str[i][j] == 'Y') stx = i, sty = j;
if(str[i][j] == 'T') edx = i, edy = j;
}
}
BFS(stx, sty, edx, edy);
}
return 0;
}
C题 HDU2717
http://acm.hdu.edu.cn/showproblem.php?pid=2717
#include <bits/stdc++.h>
#include <queue>
using namespace std;
const int MAXN = 200 + 10;
vector<int> G[MAXN];
char str[MAXN][MAXN];
int vis[MAXN][MAXN];//标记是否走过
int n, m;
struct node {
int x, y;
int step;
friend bool operator < (node a, node b) {//重载运算符
return a.step > b.step;
}
};
int d[6][3] = {{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
void BFS(int x1, int y1, int x2, int y2) {
memset(vis, 0, sizeof(vis));
priority_queue<node> que;
node now, next;//e1当前位置,e2下一步
now.x = x1, now.y = y1, now.step = 0;//起点的位置赋给e1
que.push(now);
vis[x1][y1] = 1;
int ans = -1;
while(!que.empty()) {//队列为空,说明到达终点
now = que.top();//访问最底端
que.pop();//移除最底端
if(now.x == x2 && now.y == y2) {//走到了终点
ans = now.step;
break;
}
for(int i = 0; i < 4; ++i) {
next.x = now.x + d[i][0];
next.y = now.y + d[i][1];
if(next.x < 0 || next.x >= n || next.y < 0 || next.y >= m) continue;
if(vis[next.x][next.y] == 1) continue;//已经走过
if(str[next.x][next.y] == '#') continue;//墙壁
//if(str[next.x][next.y] == 'x') next.step = now.step + 2;//遇到护卫
else next.step = now.step + 1;// else包括两种情况下一步是'.' 或'E'
que.push(next);//此点入队列
vis[next.x][next.y] = 1;
}
}
if(ans == -1) puts("Trapped!");//puts自带换行
else printf("Escaped in %d minute(s).\n", ans);
}
int main() {
int stx, sty,edx, edy;
while(scanf("%d %d", &n, &m) != EOF) {
for(int i = 0; i < n; ++i) scanf("%s", str[i]);//以字符串形式按行输入
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
if(str[i][j] == 'a') stx = i, sty = j;//起点 ,angle
if(str[i][j] == 'r') edx = i, edy = j;//终点 ,friends
}
}
BFS(stx, sty, edx, edy);
}
return 0;
}