试题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<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;
    }
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 窗外的灯光透过窗帘映入卧室的墙壁,夜里昏昏暗暗的房间显得如此的清晰。他环顾四周之后侧身面对着我,小小...
    青草尖的阳光阅读 121评论 0 0
  • 我是谁? 我是谁?我是我的名字,我是谁谁谁的妈妈,老婆,女儿,儿媳,这只是我的代名词,我的特长又是另外一种身份的认...
    不忘初心_9206阅读 91评论 0 0
  • 执子手 七子 松开绳索 我停留 在这里
    七子_868c阅读 203评论 1 1
  • 读书成长日记楼第907楼——好文章是改出来的 (第一百三十四周第3天)累积读经第907天 日期:2018年1月16...
    我爱皎皎明月阅读 267评论 0 0
  • 灯初上 映着黄昏的昏黄 天边 夕阳仍有 一些余辉 在做 一日里最后的 观望
    雪络儿阅读 261评论 1 0