7.31 练习题

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;//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;//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;
}

猜你喜欢

转载自blog.csdn.net/tingtingyuan/article/details/81298789