【最短路】埃雷萨拉斯寻宝(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 ...
随机推荐
- asp.net中ashx文件如何调用session
如果你要保证数据的安全性,你可以在ashx中使用session验证.如:你的index.aspx中使用jquery回调ashx数据,那么在index.aspx page_load时session[&q ...
- Java环境的安装与配置
Java环境的安装与配置 环境:Java8,win10 推荐oracle官网oracle官网https://www.oracle.com/index.html下载JDK进行安装 选择自己需要的版本下载 ...
- 极端气候频现 五款开发天气预报应用的API
http://www.csdn.net/article/2014-02-07/2818322-weather-forecast-api-for-developing-apps
- 最大乘积(Maximum Product,UVA 11059)
Problem D - Maximum Product Time Limit: 1 second Given a sequence of integers S = {S1, S2, ..., Sn}, ...
- phpcms 如何获取文章
请求地址http://127.0.0.1/phpcms/index.php?m=content&c=index&a=show&catid=6&id=8 先来判断地址对应 ...
- YII 创建后台模块
1,在protected/config/main.php目录下修改如下目录 'modules'=>array( // uncomment the following to enable the ...
- vsftpd.conf 联机手册
vsftpd.conf - vsftpd 的配置文件 描述vsftpd.conf 可以用于控制 vsftpd, 以实现各种各样的功能. vsftpd 缺省到 /etc/vsftpd.conf 处查找此 ...
- Javascript跳转手机站代码
$(document).ready(function(){ var mobileAgent = new Array("iphone", "ipod", &quo ...
- MSSQL中datetime与unix时间戳互转
//ms sql datetime 转unix时间戳 SELECT DATEDIFF(s, '19700101',GETDATE()) //ms sql unix时间戳 转datetime 涉及到时区 ...
- DEDECMS-helper小助手扩展
今天在做DEDE动态调用模板的时候卡住了,后终被强大的互联网解决,记录解决问题的过程,以备后用 可以在/data/helper.inc.php中进行默认小助手初始化的设置,系统默认载入小助手 例如创建 ...