ybtoj 宽搜进阶B. 2.射击问题

Posted SSL_ZZL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ybtoj 宽搜进阶B. 2.射击问题相关的知识,希望对你有一定的参考价值。

B. 2.射击问题

ybtoj 宽搜进阶 B. 2.射击问题


题面



解题思路

很容易想到,把巨龙的八个方向的直线都标记好(遇到墙就停止),只要遍历到标记的点就一定能打到龙


Code

#include <bits/stdc++.h>
#define N 200

using namespace std;

const int w[8][2] = -1, 0, 0, -1, 0, 1, 1, 0, -1, -1, -1, 1, 1, -1, 1, 1; 
int n, m, a[N][N], step[N][N], hit[N][N], v[N][N];
int sx, sy, tx, ty;
queue<pair<int, int> >q;

int che(int x, int y) 
	return (x >= 1 && x <= n && y >= 1 && y <= m);


int BFS() 
	while(!q.empty()) q.pop();
	memset(step, 0, sizeof(step));
	memset(v, 0, sizeof(v));
	v[sx][sy] = 1;
	q.push(make_pair(sx, sy));
	
	while(!q.empty()) 
		int x = q.front().first, y = q.front().second;
		q.pop();
		for(int i = 0; i < 4; i ++) 
			int xx = x + w[i][0], yy = y + w[i][1];
			if(!che(xx, yy) || !a[xx][yy] || v[xx][yy]) continue;
			
			v[xx][yy] = 1, step[xx][yy] = step[x][y] + 1;
			if(hit[xx][yy]) return step[xx][yy];
			q.push(make_pair(xx, yy));
		
	
	return -1;


int main() 
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i ++)
		for(int j = 1; j <= m; j ++) 
			char c;
			cin >> c;
			if(c == 'O') a[i][j] = 1;
		
	scanf("%d %d %d %d", &tx, &ty, &sx, &sy);
	while(sx + sy + tx + ty > 0) 
		
		memset(hit, 0, sizeof(hit));
		for(int i = 0; i < 8; i ++) 
			int xx = tx, yy = ty;
			while(che(xx, yy) && a[xx][yy]) 
				hit[xx][yy] = 1;
				xx += w[i][0], yy += w[i][1];
			
		
		
		if(hit[sx][sy]) 
			printf("0\\n");
			scanf("%d %d %d %d", &tx, &ty, &sx, &sy);
			continue;
		
		
		int ls = BFS();
		if(ls == -1) printf("Impossible!\\n");
			else printf("%d\\n", ls);
		
		scanf("%d %d %d %d", &tx, &ty, &sx, &sy);
	
 

以上是关于ybtoj 宽搜进阶B. 2.射击问题的主要内容,如果未能解决你的问题,请参考以下文章

ybtoj 宽搜进阶二分A. 1.最小权值

ybtoj 递推B. 2.求 f 函数

ybtoj 贪心B. 3.砍树问题

ybtoj 11.13 S组贪心B. 字典之序

ybtoj 深搜进阶A. 2.最大费用

ybtoj 字符串进阶A. 1.生日排序