试题J灵能传输

problemJB15.png
problemJB16.png
problemJB17.png

代码实现

存在的问题:不稳定度最高的武士数量为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 allKnights = new ArrayList();
            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;
    }
}

你可能感兴趣的:(试题J灵能传输)