Current Objective: Survive -- BFS?

我的个人博客:kingsbane.top
欢迎访问

G. Current Objective: Survive

time limit per test7.5 seconds
memory limit per test512 megabytes
inputstandard input
outputstandard output
You’re operating a merchant ship when your second mate gives you some troubling news: you’ve sailed right into pirate-infested waters, headed by none other than Captain Crawfish!

The sea can be represented as an N by M grid with two types of characters: “.” representing open water, and “#” representing land (i.e. you cannot sail on it). Your second mate has also determined the locations of all nearby pirate ships.

You are given the location of each pirate ship represented by the coordinates (xi,yi), the direction it’s facing (north, east, south, or west), and the number of locations the ship patrols, ki. Pirate ships behave in the following manner:

Each pirate ship starts in the given position.
At each minute, each pirate ship moves one unit in the direction it is facing. It is guaranteed that this move is possible, that is, it is in bounds and is not occupied by land.
When the pirate ship has moved exactly ki−1 times, meaning it has patrolled its designated ki locations, it turns 180 degrees. (The turn takes no time).
The pirate ship follows the same process in the reverse direction, traveling one unit every minute.
When the pirate ship reaches its starting location, it once again turns 180 degrees, taking no time, and repeats the process.
*Note that a ship patrolling exactly 1 location will never move.
Your ship starts in the upper left-hand corner, represented by coordinates (1,1), and you need to get to location (N,M), the lower right-hand corner. In any minute, you can either move to adjacent coordinates (north, south, east, or west) or stay where you are. (Assume north is represented by the upwards direction.) You cannot move to an adjacent coordinate if it is occupied by land, and you cannot leave the bounds of the grid (legend has it the Kraken lurks beyond the bounds of the grid). If you move to a coordinate at the same time a pirate ship does, your ship is captured!

What’s the minimum amount of time, in minutes, you need to traverse the waters without being captured and reach position (N,M)? If no path exists, output −1 and prepare to walk the plank!

Input
The first line contains two integers N,M,K representing the number of rows, number of columns, and the number of pirates, respectively. (2≤N≤100,2≤M≤100,1≤K≤2000)
The next N lines contain the contents of the sea, where “.” represents open water, and “#” represents land. It is guaranteed that the locations (1,1) and (N,M) will have water.

The next K lines describe Captain Crawfish’s pirate ships: each line contains three integers xi,yi,ki, followed by a character N,S,E, or W, where:

(xi,yi) is the starting location of the pirate ship. (1≤xi≤N,1≤yi≤M). No pirate ship will start at location (1,1).
ki represents the number of locations the pirate ship patrols. (1≤ki≤8)
The character represents the direction the pirate ship faces initially. (N-north, S-south, E-east, W-west).
Output
Print out the minimum amount of time required to get from the upper left-hand corner (1,1) to the bottom right-hand corner (N,M) without being captured. If no such path is possible, print −1.

Examples
input

5 10 2
...####...
...####...
..........
...####...
...####...
3 3 7 E
3 4 7 E

output

22

input

5 10 2
...####...
...####...
..........
...####...
...####...
3 3 6 E
3 4 6 E

output

-1

Note
For the sake of simplicity, assume all ships move instantaneously. That is, you will be captured if and only if you move to some location at the same time as a pirate ship, regardless of where you or the pirate ship came from.

Multiple pirate ships can coexist in the same location.

错在第五个案例,暂时不知道这么解决,先记录一下
思路:
开三维数组map[x][y][time],前两个分别代表x,y轴,第三个代表时间
先预处理每个海盗船的行动轨迹,比如map[x][y][0]为初始位置,map[x][y][1]为时间1的时候,在地图上标记为x,不要用#,然后bfs

#include "iostream"
#include "queue"
#include "set"
using namespace std;

#define LL long long

const int inf = 0x3f3f3f3f;
const int N = 1e4 + 5;

char map[105][105][20],instruct;
int d[10][4] = {{-1,0},{0,1},{1,0},{0,-1},{0,0}};

int book[105][105][1001];
int n,m,k,x,y,_k;
set<int> S;

struct node{
    int x,y,step;
};

int judge(int _x,int _y,int step){

    for(auto s : S){
        if(map[_x][_y][step % s] == 'x'){
            return 0;
        }
    }
    if(_x >= 1 && _x <= n && _y >= 1 && _y <= m && !book[_x][_y][step] && map[_x][_y][0] != '#'){
        return 1;
    }
    return 0;
}


int bfs(){
    queue<node> Q;
    node next,now;
    next.x = next.y = 1;
    next.step = 0;
    book[1][1][0] = 1;
    Q.push(next);
    while (!Q.empty()){
        now = Q.front();
        Q.pop();
        if(now.x == n && now.y == m){
            return now.step;
        }
        for(int i = 0; i < 5; ++i){
            next = now;
            next.x += d[i][0];
            next.y += d[i][1];
            next.step ++;
            if(judge(next.x,next.y,next.step)){
                book[next.x][next.y][next.step] = 1;
                Q.push(next);
            }
        }
    }
    return -1;
}


int main()
{
    ios::sync_with_stdio(false);

    cin >> n >> m >> k;
    for(int i = 1; i <= n; ++i){
        for(int j = 1; j <= m; ++j){
            cin >> map[i][j][0];
            for(int u = 1; u <= 14; ++u){
                map[i][j][u] = map[i][j][0];
            }
        }
    }
    for(int i = 1; i <= k; ++i){
        cin >> x >> y >> _k >> instruct;
        if(_k - 1 > 0){
            S.insert((_k - 1) * 2);
        }
        map[x][y][0] = 'x';
        for(int j = 1; j <= (_k - 1)  * 2; ++j){
            if(instruct == 'N') x--;
            if(instruct == 'S') x++;
            if(instruct == 'E') y++;
            if(instruct == 'W') y--;

            map[x][y][j] = 'x';
            if(j == _k - 1){
                if(instruct == 'N') instruct = 'S';
                else if(instruct == 'S') instruct = 'N';
                else if(instruct == 'E') instruct = 'W';
                else if(instruct == 'W') instruct = 'E';
            }
        }
    }
    cout << bfs() << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值