代码实现
存在的问题:不稳定度最高的武士数量为1时没有问题,不稳定度最高的武士数量有多个时,结果不正确。希望大佬帮忙解决一下。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
public class TestJ {
public static void main(String[] args) {
try {
// 获取文件路径
File file = new File("trans3.in");
BufferedReader bf = new BufferedReader(new FileReader(file));
// 读取组数
int groups = Integer.parseInt(bf.readLine());
// 存放每组的武士数量
int[] nums = new int[groups];
ArrayList<int[]> allKnights = new ArrayList<int[]>();
for (int i = 0; i < groups; i++) {
// 读取i组的武士数量
int numOfKnights = Integer.parseInt(bf.readLine());
// 读取所有武士
nums[i] = numOfKnights;
String line = bf.readLine();
// 存放所有武士
int[] knights = new int[numOfKnights];
// 将组所有武士存入数组
String[] lines = line.split(" ");
for (int j = 0; j < numOfKnights; j++) {
knights[j] = Integer.parseInt(lines[j]);
}
// 将i组武士存入allKnights
allKnights.add(knights);
}
bf.close();
// 对每组进行计算
for (int m = 0; m < groups; m++) {
System.out.println(getResult(nums[m], allKnights.get(m)));
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 灵能传递:
// 循环或者递归
/*
* 思路:
* 对每一组进行遍历,找出最大的一个,
* 若三组相等,返回一个值。
* 然后利用其前面两个个进行分解,
* 分解以后判断这三个是否符合,
* 有一项不符合,
* 都符合则记录最大值。进行第二次遍历,
* 若第二次最大值大于前一次再进行分解,
* 否则返回最大值为结果,
* */
/**
* @param num :武士的数量
* @param knights :所有的武士
* @return :处理后的结果
**/
public static int getResult(int num, int[] knights) {
// 数量为3只需判断一次
if (num == 3) {
int max = getMaxAbs(knights);
int[] res = transmit(1, knights);
if (max > getMaxAbs(res)) {
return getMaxAbs(res);
}
return max;
}
int max = getMaxAbs(knights);
int index = getMaxIndex(knights);
// 将最大值赋值给临时结果
int ans = max;
// 交换一次
int[] ansKnight = knights;
int[] transmitedKnight = transmit(index, knights);
while (!Arrays.equals(transmitedKnight, ansKnight)) {
// 交换后的最大值
int maxAns1 = getMaxAbs(transmitedKnight);
// 交换后最大值所在的索引
int maxIndexAns1 = getMaxIndex(transmitedKnight);
// ansKnight存放结果对应的数组
ansKnight = maxAns1 < ans ? transmitedKnight : ansKnight;
// 进行第二次传递的时候,对改变的武士数组进行交换
transmitedKnight = transmit(getMaxIndex(ansKnight), maxAns1 >= ans ? transmitedKnight : ansKnight);
ans = maxAns1 < ans ? maxAns1 : ans;
}
return ans;
}
/**
* @param knights 要传递的武士数组
* @param index 灵能最大的武士的索引
**/
public static int[] transmit(int index, int[] knights) {
int[] list = knights.clone();
// 前面可以传递,先传前面
if (index - 2 >= 0) {
int temp = list[index - 1];
list[index - 2] += temp;
list[index - 1] -= 2 * temp;
list[index] += temp;
}
// 后面可以传递先传后面
if (index + 2 <= list.length - 1) {
int temp = list[index + 1];
list[index] += temp;
list[index + 1] -= 2 * temp;
list[index + 2] += temp;
}
return list;
}
// 获取最大绝对值所在的索引
public static int getMaxIndex(int[] list) {
int index = 0;
int max = 0;
for (int i = 0; i < list.length; i++) {
if (Math.abs(list[i]) > max) {
index = i;
}
}
return index;
}
// 获取最大绝对值
public static int getMaxAbs(int[] list) {
int max = Math.abs(list[0]);
for (int i = 0; i < list.length; i++) {
if (Math.abs(list[i]) > max) {
max = Math.abs(list[i]);
}
}
return max;
}
}