列表

详情


NC200442. 《巫妖王的远征》

描述

“他的邪恶乃是一个传奇。他是亡灵天灾的君王,是符文圣剑霜之哀伤的主人,是艾泽拉斯世界一切自由族类的大敌。

巫妖王是无与伦比的强大力量与极端冷酷的化身,他比寒冰更加寒冷的灵魂已经被他的宏大计划彻底吞噬。

在这个计划中,他将毁灭世界上的全部生灵。

巫妖王-阿尔萨斯已经启动了可能导致艾泽拉斯所有生灵毁灭的计划,他的天灾军团和驱役亡灵的强大力量将横扫整个世界。

我们可以将艾泽拉斯视为nm的矩阵,其中

S:寒冰王座,起点

T:暴风城,终点

:平原,天灾军团可以到达的地方

#:沼泽,天灾军团无法到达的地方

在地图上存在着 个传送门,借助传送门,可以瞬间(不花费时间地)从传送门的任一端到达另一端

天灾军团每小时可以向其周围4个方向移动一格(上下左右),为了保证天灾军团随时保持最高战斗力,巫妖王命令军队每行军8小时,就原地休息1小时。

现在巫妖王率领他的天灾军团从S出发,问最快多久可以到达T


输入描述

第1行两个整数n,m (1<= n, m<=1000 , 且n,m不同时等于1)

第2到n+1行每行含有m个字符,其中:

第n+2行有一个整数k(0 <= k <= 10)

随后k行,每行包含4个整数x1,y1,x2,y2表示传送门两端的坐标(x1,y1),(x2,y2)

(1 <= x1,x2 <= n ,1<= y1,y2<= m)

(注意,传送门也可以直接存在于S和T之间,同时,同一个传送门的两端可能在同一个位置,但是一个地点不可能有多个传送门的一端)

输出描述

输出仅一行,表示巫妖王到达暴风城的最短时间,如果无法到达,则输出-1

示例1

输入:

4 8
S***###T
*####***
*##****#
**#*##**
1
1 4 4 8

输出:

8

示例2

输入:

4 8
S#***#*T
*#*#*#*#
*#*#*#*#
***#***#
0

输出:

21

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 72ms, 内存消耗: 9344K, 提交时间: 2022-08-10 14:25:01

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<map>
#define INF 0x3f3f3f3f
using namespace std;
int n,m,k,sx,sy,tx,ty;
char ditu[1005][1005];
int vis[1005][1005],tp[1005][1005];
int dir[4][2]={0,1,1,0,0,-1,-1,0};
map<pair<int,int>,pair<int,int> >ma;
queue<pair<int,int>> q;
void bfs(){
    q.push(pair<int,int>(sx,sy));
    vis[sx][sy]=0;
    while(!q.empty()){
        pair<int,int> tmp=q.front();q.pop();
        int x=tmp.first,y=tmp.second;
        for(int i=0;i<4;i++){
            int xx=x+dir[i][0],yy=y+dir[i][1];
            if(xx>0&&xx<=n&&yy>0&&yy<=m&&ditu[xx][yy]!='#'&&vis[xx][yy]>vis[x][y]+1){
                vis[xx][yy]=vis[x][y]+1;
                q.push(pair<int,int>(xx,yy));
            }
        }
        if(tp[x][y]){
            int xx=ma[pair<int,int>(x,y)].first,yy=ma[pair<int,int>(x,y)].second;
                if(vis[xx][yy]>vis[x][y]){
                    vis[xx][yy]=vis[x][y];
                    q.push(pair<int,int>(xx,yy));
                }
        }
    }

    if(vis[tx][ty]==INF)cout<<"-1"<<endl;
    else if(vis[tx][ty]==0)cout<<"0"<<endl;
    else cout<<vis[tx][ty]+((vis[tx][ty]-1)/8 )<<endl;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>ditu[i][j];
            if(ditu[i][j]=='T'){
                tx=i,ty=j;
            }
            if(ditu[i][j]=='S'){
                sx=i,sy=j;
            }
        }
    }
    memset(vis,INF,sizeof(vis));
    memset(tp,0,sizeof(tp));
    cin>>k;
    for(int i=0;i<k;i++){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        tp[a][b]=tp[c][d]=1;
        ma[pair<int,int>(a,b)]=pair<int,int>(c,d);
        ma[pair<int,int>(c,d)]=pair<int,int>(a,b);
    }
    bfs();
    return 0;
}

C++14(g++5.4) 解法, 执行用时: 28ms, 内存消耗: 5252K, 提交时间: 2019-12-17 19:26:45

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 1005;
const int MOD = 1e9+7;
char mp[MAXN][MAXN];
map<pair<int,int>,pair<int,int> > v;
struct node{ int x,y,step; };
int vis[MAXN][MAXN],n,m,stx,sty;
int dir[][2]={{0,1},{0,-1},{1,0},{-1,0}};
inline bool check(int x,int y){
    if(x<1 || x>n || y<1 || y>m || mp[x][y]=='#' || vis[x][y]) return false;
    return true;
}
inline int bfs(int sx,int sy){
    queue<node> que;
    que.push({sx,sy,0}); vis[sx][sy]=1;
    while(!que.empty()){
        node u=que.front(); que.pop();
        if(mp[u.x][u.y]=='T') return u.step;
        if(v.count({u.x,u.y})){
            int x=v[{u.x,u.y}].first,y=v[{u.x,u.y}].second;
            if(check(x,y)){
                vis[x][y]=1; que.push({x,y,u.step});
            }
        }
        for(int i=0;i<4;i++){
            int xx=u.x+dir[i][0],yy=u.y+dir[i][1];
            if(check(xx,yy)){
                vis[xx][yy]=1;
                if((u.step+1)%9==0) que.push({xx,yy,u.step+2});
                else que.push({xx,yy,u.step+1});
            }
        }
    }
    return -1;
}
int main(){
    //freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(mp[i][j]=='S')
                stx=i,sty=j;
    int k; scanf("%d",&k);
    for(int i=1;i<=k;i++){
        int x,y,xx,yy; scanf("%d%d%d%d",&x,&y,&xx,&yy);
        v[{x,y}]={xx,yy};
        v[{xx,yy}]={x,y};
    }
    printf("%d\n",bfs(stx,sty));
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 76ms, 内存消耗: 5480K, 提交时间: 2019-12-15 14:24:53

#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
const int INF=0x3f3f3f3f;
char s[N][N];
int n,m,k,S,E;
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
int d[N*N];
unordered_map<int,int> ma;
int main() {
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%s",s[i]);
    for(int i=0;i<n;i++) {
        for(int j=0;j<m;j++) {
            if(s[i][j]=='S') S=i*m+j;
            if(s[i][j]=='T') E=i*m+j;
        }
    }
    scanf("%d",&k);
    for(int i=0,x1,x2,y1,y2;i<k;i++) {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        x1--,x2--,y1--,y2--;
        ma[x1*m+y1]=x2*m+y2;
        ma[x2*m+y2]=x1*m+y1;
    }
    memset(d,INF,sizeof d);
    queue<int> qu;
    qu.push(S),d[S]=0;
    while(!qu.empty()) {
        int u=qu.front();qu.pop();
        for(int i=0;i<4;i++) {
            int x=u/m+dx[i],y=u%m+dy[i];
            if(x<0||x>=n||y<0||y>=m||s[x][y]=='#') continue;
            if(d[x*m+y]>d[u]+1) {
                d[x*m+y]=d[u]+1;
                qu.push(x*m+y);
            }
        }
        if(ma.count(u)) {
            if(d[ma[u]]>d[u]) {
                d[ma[u]]=d[u];
                qu.push(ma[u]);
            }
        }
    }
    if(d[E]==INF) printf("-1\n");
    else printf("%d\n",d[E]+(d[E]-1)/8);
    return 0;
}

上一题