标题:灵能传输(时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分)
【题目背景】
在游戏《星际争霸 II》中,高阶圣堂武士作为星灵的重要 AOE 单位,在
游戏的中后期发挥着重要的作用,其技能”灵能风暴“可以消耗大量的灵能对
一片区域内的敌军造成毁灭性的伤害。经常用于对抗人类的生化部队和虫族的
刺蛇飞龙等低血量单位。
【问题描述】
你控制着 n 名高阶圣堂武士,方便起见标为 1,2,··· ,n。每名高阶圣堂武士
需要一定的灵能来战斗,每个人有一个灵能值 a i 表示其拥有的灵能的多少(a i
非负表示这名高阶圣堂武士比在最佳状态下多余了 a i 点灵能,a i 为负则表示这
名高阶圣堂武士还需要 −a i 点灵能才能到达最佳战斗状态) 。现在系统赋予了
你的高阶圣堂武士一个能力,传递灵能,每次你可以选择一个 i ∈ [2,n − 1],若
a i ≥ 0 则其两旁的高阶圣堂武士,也就是 i − 1、i + 1 这两名高阶圣堂武士会从
i 这名高阶圣堂武士这里各抽取 a i 点灵能;若 a i < 0 则其两旁的高阶圣堂武士,
也就是 i−1,i+1 这两名高阶圣堂武士会给 i 这名高阶圣堂武士 −a i 点灵能。形
式化来讲就是 a i−1 + = a i ,a i+1 + = a i ,a i − = 2a i 。
灵能是非常高效的作战工具,同时也非常危险且不稳定,一位高阶圣堂
武士拥有的灵能过多或者过少都不好,定义一组高阶圣堂武士的不稳定度为
max n
i=1 |a i |,请你通过不限次数的传递灵能操作使得你控制的这一组高阶圣堂武
士的不稳定度最小。
【输入格式】
本题包含多组询问。输入的第一行包含一个正整数 T 表示询问组数。
接下来依次输入每一组询问。
每组询问的第一行包含一个正整数 n,表示高阶圣堂武士的数量。
接下来一行包含 n 个数 a 1 ,a 2 ,··· ,a n 。
试题 J: 灵能传输 15
第十届蓝桥杯大赛软件类省赛C/C++大学B组
【输出格式】
输出 T 行。每行一个整数依次表示每组询问的答案。
【样例输入】
3
3
5 -2 3
4
0 0 0 0
3
1 2 3
【样例输出】
3
0
3
【样例说明】
对于第一组询问:
对 2 号高阶圣堂武士进行传输操作后 a 1 = 3,a 2 = 2,a 3 = 1。答案为 3。
对于第二组询问:
这一组高阶圣堂武士拥有的灵能都正好可以让他们达到最佳战斗状态。
【样例输入】
3
4
-1 -2 -3 7
4
2 3 4 -8
5
-1 -1 6 -1 -1
【样例输出】
5
7
4
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
int m = sc.nextInt();
int[] list = new int[m];
for (int j = 0; j < m; j++) {
list[j] = sc.nextInt();
}
ans[i] = computer(list);
}
sc.close();
for (int i = 0; i < n; i++) {
System.out.println(ans[i]);
}
}
public static int computer(int[] list) {
int max = 0, n = list.length;
if (n == 1)
return list[0];
if (n == 2)
return (list[0] + list[1]) / 2;
max=max(list);
max = update(list, max, 1);
return max;
}
public static int update(int[] list, int max, int index) {
int n = list.length, ans = max;
for (int i = index; i < n - 1; i++) {
int tmp = Integer.MIN_VALUE;
list[i - 1] += list[i];
list[i + 1] += list[i];
list[i] = -list[i];
int m=max(list);
m = (Math.abs(max) > Math.abs(m)?m:max);
int t = update(list, m, i + 1);
// 回撤
list[i - 1] += list[i];
list[i + 1] += list[i];
list[i] = -list[i];
ans =min(t,m,ans);
}
return ans;
}
public static int min(int a,int b,int c) {
if(Math.abs(a)>Math.abs(b)) {
if(Math.abs(b)>Math.abs(c)) {
return c;
}else {
return b;
}
}else {
if(Math.abs(a)>Math.abs(c)) {
return c;
}else {
return a;
}
}
}
public static int max(int[] list) {
int n=list.length,max=0;
for (int i = 0; i < n; i++) {
int ab = Math.abs(list[i]);
if (ab > max) {
max = ab;
}
}
return max;
}
}