(File IO): input:attack.in output:attack.out
时间限制: 1000 ms 空间限制: 262144 KB 具体限制
Goto ProblemSet
题目描述
月球上反凤凰装甲在凤凰之力附身霍普之前,将凤凰之力打成五份,分别附身在X战警五大战力上面辐射眼、白皇后、钢力士、秘客和纳摩上(好尴尬,汗)。
在凤凰五使徒的至高的力量的威胁下,复仇者被迫逃到昆仑的一座山上,因为凤凰五使徒监视不到那里。
霍普加入了复仇者,为了磨练自己,她在个山峰之间跳跃。
这个山峰在一条直线上,每个山峰都有不同的高度,只知道这些山峰在水平上相对位置。霍普可以将这些山峰左右移动但不能改变他们的相对位置(要保证两两山峰间距为整数且大于等于)。霍普要从最矮的山峰开始跳,每次跳向第一个比现在她所在的山峰高的山峰,一共跳次,由于能力有限,每次跳跃的水平距离小于等于。
霍普想知道如何移动这些山峰,使得在可以经过所有的山峰并跳到最高的山峰上的基础下,又要使最矮的山峰和最高的山峰的水平距离最远,霍普要你求出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出。
输入
输入文件名为。
本题每个测试点有多组数据,
在第一行中有一个整数,表示数据的数目
对于每组数据:
第一行包含两个整数和。
下一行包含个整数,给出个山峰的高度,输入顺序即为山峰在水平上的相对顺序。在每个数据中,所有的高度都是唯一的。
输出
输出文件名为。
输出共t行。
对于每组数据输出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出。
样例输入
3
4 4
20 30 10 40
5 6
20 34 54 10 15
4 2
10 20 16 13
样例输出
3
3
-1
数据范围限制
【数据说明】
对于100%的数据,1≤n≤1000,1≤d≤1000000
解题思路
思路:最短路()+排序
1、两个山峰之间水平距离至少为(因为山峰不能再同一位置上)。
2、霍普每次最多跳的水平距离。
对于第一个条件,对于两个相邻的山峰,相对位置(即输入顺序)大的向相对位置小的连一条的边。
对于第二个条件,对于两个高度排名相邻的山峰,相对位置小的向相对位置大的连一条的边。
然后比较最高和最低的山峰,从相对位置小的那个山峰出发,跑一遍最短路,输出到相对位置大的山峰的距离。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
long long head[10000],dis[1010],v[1010],st[10000010],qq[2000];
int t,n,d,len,he,ta,aa;
struct c {
int x,y;
}a[10000];
struct cc {
int x,y,z;
}b[10000];
void add(int x,int y,int z)
{
b[++len].x=y;
b[len].y=z;
b[len].z=head[x];
head[x]=len;
}
bool cmp(const c&l,const c&r)
{
return l.x<r.x;
}
void spfa()
{
memset(dis,127,sizeof(dis));
memset(v,0,sizeof(v));
memset(qq,0,sizeof(qq));
he=0,ta=1;
if(a[1].y<a[n].y)aa=1;
else aa=n;
st[1]=a[aa].y;
dis[a[aa].y]=0;
v[a[aa].y]=1;
qq[a[aa].y]=1;
while(he<=ta) {
he++;
int x=st[he];
for(int i=head[x]; i; i=b[i].z) {
if(dis[b[i].x]>dis[x]+b[i].y) {
dis[b[i].x]=dis[x]+b[i].y;
qq[b[i].x]++;
if(qq[b[i].x]<1000)
if(!v[b[i].x]) {
++ta;
v[b[i].x]=1;
st[ta]=b[i].x;
}
}
}
v[x]=0;
}
}
int main()
{
freopen("attack.in","r",stdin);
freopen("attack.out","w",stdout);
scanf("%d",&t);
for(int i=1; i<=t; i++) {
memset(head,0,sizeof(head));
memset(b,0,sizeof(b));
len=0;
memset(a,0,sizeof(a));
scanf("%d%d",&n,&d);
for(int i=1; i<=n; i++) {
scanf("%d",&a[i].x);
a[i].y=i;
if(i!=1)add(i,i-1,-1);
}
sort(a+1,a+n+1,cmp);
for(int i=2; i<=n; i++)
if(a[i].y<a[i-1].y) add(a[i].y,a[i-1].y,d);
else add(a[i-1].y,a[i].y,d);
spfa();
aa=n+1-aa;
if(dis[a[aa].y]<=0)printf("-1\n");
else
printf("%d\n",dis[a[aa].y]);
}
}
来源:CSDN
作者:SSL KJ
链接:https://blog.csdn.net/kejin2019/article/details/104225472