国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

HDU - 3533 bfs [kuangbin帶你飛]專題二

2019-11-08 02:54:33
字體:
來源:轉載
供稿:網友

     看了好久的樣例才看懂。

    題意:有一個人要從(0,0)走到(n,m),圖中有k個碉堡,每個碉堡可以向某個固定的方向每隔t秒放一次炮,炮彈不能穿越另一個碉堡,會被阻擋。人在移動的過程中不會被炮彈打到,也就是說只有炮彈和人在某個整數時間待在同一個位置人才會被打死。問人能否到達(n,m)。

  思路:直接bfs即可,shot[t][x][y]表示在t時刻,是否有炮彈在(x,y)這個位置,可以預處理該數組。

  注意:

1. 人不能穿越碉堡。

2. 炮彈每隔t秒發射一次,炮彈不能穿越其他碉堡。

3. 樣例1中人必須在(2,0)這個位置待一秒避開炮彈才能繼續走,所以總共需要8 + 1秒。

4.  剪枝:當前已經用了x能量,還剩w能量,距離終點dis,如果w < dis說明根本到不了終點,剪掉。距離是曼哈頓距離。

5. 輸入的是m和n,代表m行,n列。后面的t表示間隔,v表示炮彈速度,x表示第x行,y表示第y列。

AC代碼: 982ms

#include<cstdio>#include<queue>#include<vector>#include<cmath>#include<cstring>using namespace std;const int maxn = 100 + 3;bool vis[1003][maxn][maxn], pic[maxn][maxn], shot[1003][maxn][maxn];int n, m, k, d;const int dx[] = {-1,1,0,0,0}; //上-下-左-右 const int dy[] = {0,0,-1,1,0};struct castle {	char dir;	int t, v, x, y;	castle() {	}	castle(char dir, int t, int v, int x, int y):dir(dir),t(t),v(v),x(x),y(y){	} };vector<castle>vec;void deal() {	memset(shot, false, sizeof(shot));	int len = k;	for(int i = 0; i < len; ++i) {		int x = vec[i].x, y = vec[i].y;		int dir;		switch(vec[i].dir) {			case 'N': dir = 0; break;			case 'S': dir = 1; break;			case 'W': dir = 2; break;			case 'E': dir = 3; break;		}		for(int j = 1;;++j) { //判斷子彈到達的最遠位置 			int px = x + j * dx[dir], py = y + j * dy[dir];			if(px < 0 || py < 0 || px > n || py > m) break; //達到邊界			if(pic[px][py]) break; //有其他炮塔擋住			if(j % vec[i].v == 0) { //子彈停留的坐標 				for(int h = j / vec[i].v; h <= d; h += vec[i].t) {					shot[h][px][py] = true; //標記這個位置在j時刻會被子彈打到 				}			}		}	}}struct Move{	int time;	int x, y;	Move(){	}	Move(int time, int x, int y): time(time), x(x), y(y) {	}};bool judge(int x, int y, int time) { //判斷當前位置已用了time時間是否還有可能到達終點 	int man = abs(n - x) + abs(m - y); //曼哈頓距離 	if(d - time < man) return false;	return true;}int bfs() {	if(shot[0][0][0]) return -1; 	memset(vis, false, sizeof(vis));	queue<Move>q;	vis[0][0][0] = true;	q.push(Move(0, 0, 0));	while(!q.empty()) {		Move p = q.front();		q.pop();		int x = p.x, y = p.y, t = p.time;		if(!judge(x, y, t)) continue; //無法到達		if(x == n  && y == m ) return p.time;		for(int i = 0; i < 5; ++i) {			int px = x + dx[i], py = y + dy[i];			if(px < 0 || py < 0 || px > n || py > m) continue; //達到邊界			if(vis[t + 1][px][py] ||  pic[px][py] || shot[t + 1][px][py] || t + 1 > d) continue;			vis[t + 1][px][py] = true;			q.push(Move(t + 1, px, py));		}	}	return -1;}int main() {	while(scanf("%d%d%d%d", &n, &m, &k, &d) == 4) {		getchar();		memset(pic, false, sizeof(pic));		vec.clear();		char dir;		int t, v, x, y;		for(int i = 0; i < k; ++i) {			scanf("%c%d%d%d%d", &dir, &t, &v, &x, &y);			pic[x][y] = true; //標記碉堡位置 			vec.push_back(castle(dir, t, v, x, y));			getchar(); //接收換行 		}		deal(); 		//for(int i = 0; i < 8; ++i) PRintf("%d/n", (int)shot[i][2][0]);		int step = bfs();		if(step == -1) printf("Bad luck!/n");		else printf("%d/n", step);	}		return 0;}如有不當之處歡迎指出!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿拉善右旗| 泰安市| 德阳市| 安乡县| 久治县| 敦煌市| 成都市| 祁连县| 临颍县| 曲周县| 正安县| 科技| 密山市| 马公市| 潞城市| 聂荣县| 永川市| 从化市| 彩票| 大化| 扎赉特旗| 大洼县| 湘阴县| 喜德县| 稷山县| 双鸭山市| 千阳县| 原平市| 湘西| 和田县| 广西| 汽车| 阿拉尔市| 通化市| 寻乌县| 长春市| 麻江县| 留坝县| 荣昌县| 紫阳县| 边坝县|