【最短路】埃雷萨拉斯寻宝(eldrethalas) 解题报告
问题来源
BYVoid魔兽世界模拟赛
【问题描述】
一万两千年前,当精灵还是在艾萨拉女王的统治下的时候,辛德拉就是是女王手下一名很有地位的法师了。他受任建造了一座城市,来保存女王的法师们进行魔法研究的成果和法术物品。这个城市就是埃雷萨拉斯。永恒之井爆炸以后,埃雷萨拉斯的精灵和艾萨拉联系中断,并失去了永恒之井的水做为能量的来源。辛德拉的后人为了对满足魔法的欲望,他们捕猎了一个恶魔,伊莫塔尔。他们用水晶塔建造了一个带有能量平衡系统的结界监狱,水晶塔从恶魔身上吸取能量,一部分维持结界监狱,一部分可以让狂热的精灵们吸收。这个系统万年以来一直平安无事,可是现在,随着恶魔的能量被消耗殆尽,已经难以维持结界监狱的消耗。统治者托尔塞林王子为了满足自己的欲望,开始下令屠杀,除了少数狂热者之外的其他人都要死,这样才能减少对魔法能量的消耗。终于有一天,戈多克食人魔成功入侵了埃雷萨拉斯,并杀死了几乎所有的精灵。他们把这里当作自己王国的领地,名叫厄运之槌。面临着灭顶之灾的精灵们把他们祖先留下的宝藏用魔法结界藏了起来,以防戈多克食人魔抢走。
作为一名勇敢的探险者,你悄悄来到了埃雷萨拉斯寻找传说中的宝藏。终于,你看见宝藏就在你的前方不远处。但是你不能贸然前进,因为路上有着强大的魔法结界。这些结界根据能量的不同分为P种,踏入每种结界,你都会受到一定的伤害。为了拿到宝藏,这些伤害算不了什么。但是你要尽可能地减少伤害,请你设计一条路线,使你穿越结界获取宝藏受到的伤害最少。下面是一个魔法结界能量示意图,结界是一个正方形,内部有P种不同的能量,每种字母表示一种能量。你从最上端开始走,每次可以走到与你所在的位置上下左右相邻的临位,或者在同种能量结界中任意传送。重复进入同一种能量结界不会再次受到伤害。
|AAABBC|
|ABCCCC|
|AABBDD|
|EEEEEF|
|EGGEFF|
|GGFFFF|
你有H点生命值,请你在贸然行动之前先判断是否能够活着(生命值大于0)穿越结界拿到宝藏,如果能够,请求出最多剩余的生命值。
【输入格式】
第1行 三个非负整数 N,P,H。N为结界的边长,P为不同的能量结界的数量,H为你的生命值。
第2-P+1行 每行一个非负整数,表示走到该种能量结界受到的伤害值。
第P+2至第P+2+N行 每行N个正整数,为地图上该单元格的能量种类的编号,编号为1..P。
【输出格式】
如果你能够穿越结界到达对岸的宝藏,输出最多剩余的生命值。如果不能穿越,输出NO。
【输入样例】
6 7 10
3
1
2
2
1
1
3
1 1 1 2 2 3
1 2 3 3 3 3
1 1 2 2 4 4
5 5 5 5 5 6
5 7 7 5 6 6
7 7 6 6 6 6
【输出样例】
7
【数据说明】
路线为
起始-2-5-6-目标
1 1 1 2 2 3
1 2 3 3 3 3
1 1 2 2 4 4
5 5 5 5 5 6
5 7 7 5 6 6
7 7 6 6 6 6
对于40%数据
4<=N<=10 对于100%数据
4<=N<=50
1<=P<=N*N
0<=H<=200000000
分析
最短路的变形,添加超级源(到第一行的距离为0),加入标记的传递(记录经过那些结界)就可以AC了,考试时由于没处理好所以WA了一个点。
/*
ID: ringxu97
LANG: C++
TASK: eldrethalas
SOLUTION: 最短路
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
using namespace std; typedef pair<int,int> pii;
const int inf=0x3f3f3f3f;
const int maxn=+;
const int maxp=maxn*maxn;
int N,P,H;
int hurt[maxp];//进入受到的伤害
int G[maxn][maxn];//记录
bool vis[maxn][maxn][maxp];//是否到过该种结界
int dist[maxn][maxn];//dist[i][j]表示到i,j的最小代价
bool inq[maxn][maxn];//i,j节点是否在数组中
queue<pii>Q; void init()//初始化
{
memset(hurt,,sizeof(hurt));
memset(vis,,sizeof(vis));
memset(inq,,sizeof(inq));
for(int i=;i<=N;++i)
for(int j=;j<=N;++j)
{
dist[i][j]=inf;
}
}
void read()//读入数据
{ scanf("%d%d%d",&N,&P,&H);
init();
for(int i=;i<=P;++i)scanf("%d",hurt+i);
for(int i=;i<=N;++i)
for(int j=;j<=N;++j)
{
scanf("%d",&G[i][j]);
if(i==)//初始化第一行
{
dist[i][j]=hurt[G[i][j]];
Q.push(make_pair(i,j));
vis[i][j][G[i][j]]=;
inq[i][j]=;
}
}
}
const int dx[]={,,,,-};
const int dy[]={,,-,,};
inline bool check(int i,int j){return (<=i && i<=N && <=j && j<=N);}
void SPFA()
{
while(!Q.empty())
{
pii u=Q.front();Q.pop();
inq[u.first][u.second]=;
//vis[u.first][u.second][G[u.first][u.second]]=1;
for(int k=;k<=;++k)if(check(u.first+dx[k],u.second+dy[k]))//扩展周围节点
{
//pii v=make_pair(u.first+dx[k],u.second+dy[k]);
int relax=dist[u.first][u.second];
if(G[u.first+dx[k]][u.second+dy[k]]!=G[u.first][u.second]/*结界种类不同*/ && !vis[u.first][u.second][G[u.first+dx[k]][u.second+dy[k]]]) /*没有到过该种结界*/
{
relax+=hurt[G[u.first+dx[k]][u.second+dy[k]]];//加入伤害
}
if(dist[u.first+dx[k]][u.second+dy[k]]>relax)
{
dist[u.first+dx[k]][u.second+dy[k]]=relax;//松弛
if(!inq[u.first+dx[k]][u.second+dy[k]])
{
memcpy(vis[u.first+dx[k]][u.second+dy[k]],vis[u.first][u.second],sizeof(vis[u.first+dx[k]][u.second+dy[k]]));
vis[u.first+dx[k]][u.second+dy[k]][G[u.first+dx[k]][u.second+dy[k]]]=;
inq[u.first+dx[k]][u.second+dy[k]]=;
Q.push(make_pair(u.first+dx[k],u.second+dy[k]));
}
}
}
for(int i=;i<=N;++i)//扩展图中同类结界
for(int j=;j<=N;++j)
if(G[i][j]==G[u.first][u.second] && dist[i][j]>dist[u.first][u.second])//不在队列中 AND 同类 AND 可以松弛
{
vis[i][j][G[i][j]]=;
dist[i][j]=dist[u.first][u.second];//松弛
if(!inq[i][j])
{
inq[i][j]=;//加入队列
Q.push(make_pair(i,j));
memcpy(vis[i][j],vis[u.first][u.second],sizeof(vis[i][j]));
} }
}
} void print()//打印
{
/*
for(int i=1;i<=N;++i)
for(int j=1;j<=N;++j)
{
printf("%2d ",dist[i][j]);
if(j==N)printf("\n");
}*/
int ans=inf;
for(int i=;i<=N;++i)
{
ans=min(ans,dist[N][i]);
}
ans=H-ans;
if(ans>)printf("%d\n",ans);
else printf("NO\n");
}
int main()
{
freopen("eldrethalas.in", "r", stdin);
freopen("eldrethalas.out", "w", stdout);
read();
SPFA();
print();
return ;
}
【最短路】埃雷萨拉斯寻宝(eldrethalas) 解题报告的更多相关文章
- 【最短路】血色先锋军(scarlet) 解题报告
问题来源 BYVoid魔兽世界模拟赛 [问题描述] 巫妖王的天灾军团终于卷土重来,血色十字军组织了一支先锋军前往诺森德大陆对抗天灾军团,以及一切沾有亡灵气息的生物.孤立于联盟和部落的血色先锋军很快就遭 ...
- P3320 [SDOI2015]寻宝游戏 解题报告
P3320 [SDOI2015]寻宝游戏 题目描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有\(N\)个村庄和\(N-1\)条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...
- 【模拟赛】BYVoid魔兽世界模拟赛 解题报告
题目名称(点击进入相关题解) 血色先锋军 灵魂分流药剂 地铁重组 埃雷萨拉斯寻宝 源文件名(.c/.cpp/.pas) scarlet soultap subway eldrethalas 输入文件名 ...
- 10.30 NFLS-NOIP模拟赛 解题报告
总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...
- hdu1853解题报告
题意和解决回路匹配的思路如同hdu3488 (这里我第一次想到最短路,但是对于有回路这个不知道怎么处理,后来看了别人的解题报告才知道KM匹配,但是看到KM之后就自己想...想了很久....还是不知道回 ...
- GX/GZOI2019 day2 解题报告
GX/GZOI2019 day2 解题报告 题目链接 逼死强迫症 旅行者 旧词 t1 逼死强迫症 显然地,记 \(f(i)\) 为长度为 \(i\) 的木板的答案,可得: \(\\\) \[f(i)= ...
- 「ZJOI2016」解题报告
「ZJOI2016」解题报告 我大浙的省选题真是超级神仙--这套已经算是比较可做的了. 「ZJOI2016」旅行者 神仙分治题. 对于一个矩形,每次我们从最长边切开,最短边不会超过 \(\sqrt{n ...
随机推荐
- System.Data.DbType的字符串和数据库中字符串类型对应关系
前两天项目中因为历史原因数据库中的一个字段是varchar类型,在做SQL参数化处理时候默认都是DbType.String, 免得查询出现数据转换,于是做类型一致,搜了下对应关系还没找到,只好自己打开 ...
- jquery 操作 checkbox
对checkbox的其他几个操作 1. 全选2. 取消全选3. 选中所有奇数4. 反选5. 获得选中的所有值 js代码 $("document").ready(function() ...
- Axis,axis2,Xfire以及cxf对比 (转)
Axis,axis2,Xfire以及cxf对比 http://ws.apache.org/axis/ http://axis.apache.org/axis2/java/core/ http:// ...
- svn的初级使用
首先呢 你需要下载一个软件 比如说是 Cornerstone. 进行安装好之后 然后 然后输入账号密码 就可以了 然后去xcode去进行相关的配置 点击第二个进入 偏好设置 点击最下边的+ 点击第二 ...
- 【POJ1823】【线段树】Hotel
Description The "Informatics" hotel is one of the most luxurious hotels from Galaciuc. A l ...
- 【BZOJ1500】【块状链表】维修数列
Description Input 输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述 ...
- python3 读取大文件分解成若干小文件
有个数据实在太大了,有1.7G,打开慢,改文件也慢,我们将其分解成若干个中等文件 #!/usr/bin/env python3 # -*- coding: utf-8 -*- f = open(& ...
- [转]我的第一个WCF
1:首先新建一个解决方案 2:右击解决方案添加一个控制台程序 3:对着新建好的控制台程序右击添加wcf服务 最后的结果: 有3个文件 app.config Iwcf_server.cs wcf_se ...
- js字符串倒序
有的时候我们需要把字符串倒序. 比如“范坚强”的倒序就是“强坚范”. 如何对字符串进行倒序呢?你首先想到的方法就是生成一个栈,从尾到头依次取出字符串中的字符压入栈中,然后把栈连接成字符串. var r ...
- ThinkPHP 笔记
1.循环中使用比较运算符 <volist name="subjects" id="v"> <option value=" ...