zoukankan      html  css  js  c++  java
  • 笔试算法题目,奶牛排队喝水

    import java.util.*;
    /**
     * Created by Daxin on 2017/8/19.
     * <p/>
     * 奶牛排队饮水问题
     * 输入:n牛的数目,然后n个整数表示牛的序号
     * 输出:输出交换最少次数
     * <p/>
     * 例如一个测试用例:9<br>
     * 2,2,1,3,3,3,2,3,1<br>
     * 输出:4
     *
     *在线题目地址:http://www.hustoj.com/oj/problem.php?id=1056
     *
     *
     */
    public class CattleSortWater {
        public static void main(String[] args) {
    //        int[] nums = {2, 2, 1, 3, 3, 3, 2, 3, 1};
            Scanner cin = new Scanner(System.in);
            int n = cin.nextInt();
            int[] nums = new int[n];
            for (int i = 0; i < n; i++) {
                nums[i] = cin.nextInt();
            }
            System.out.println(solve(nums));
    //        System.out.println(Arrays.toString(nums));
        }
        public static int solve(int[] nums) {
            int result = 0;
            Map<Integer, Integer> wcount = new TreeMap<>();
            Map<Integer, Integer> range = new TreeMap<>();
            for (int num : nums) {
                Integer tmp = wcount.get(num);
                wcount.put(num, tmp == null 1 : tmp + 1);
            }
            Set<Integer> set = wcount.keySet();
            int pre = 0;
            for (int i : set) {
                int tmp = wcount.get(i) + pre;
                range.put(i, tmp);
                pre = tmp;
            }
            for (int num : set) {
                int times = wcount.get(num);
                int ran = range.get(num);
                for (int i = ran - 1, t = times; t > 0; t--, i--) {
                    if (nums[i] != num) {
                        int r = get(nums, range.get(nums[i]), wcount.get(nums[i]), num);
                        if (r != -1) { //在nums[i] 区间中寻找到了num
                            int tmp = nums[r];
                            nums[r] = nums[i];
                            nums[i] = tmp;
                            result++;
                        else {// 在希望区间没有找到,进行余下遇见全扫描
                            int rr = getRange(nums, ran, num,range.get(nums[i])-wcount.get(nums[i]),range.get(nums[i]));
                            if (rr != -1) {
                                int tmp = nums[rr];
                                nums[rr] = nums[i];
                                nums[i] = tmp;
                                result++;
                            }
                        }
                    }
                }
            }
            return result;
        }
        /**
         *
         * @param nums 数组
         * @param range 结束的下标
         * @param times 出现的次数,range-times就是起始下标
         * @param expect 希望查找的希望值
         * @return
         */
        public static int get(int[] nums, int range, int times, int expect) {
            for (int i = range - 1, t = times; t > 0; t--, i--) {
                if (nums[i] == expect) {
                    return i;
                }
            }
            return -1;
        }
        /**
         *
         * @param nums 数组
         * @param start 查找的起始位置,结束位置是数组的结束
         * @param expect 期望寻找到的值
         * @param exceptStart 排除区域的起始下标
         * @param exceptEnd 排除区域的结束下标
         * @return 返回下标
         */
        public static int getRange(int[] nums, int start, int expect,int exceptStart,int exceptEnd) {
            for (; start < nums.length; start++) {
                if(start>=exceptStart&&start<exceptEnd)
                    continue;
                if (nums[start] == expect) {
                    return start;
                }
            }
            return -1;
        }
    }
  • 相关阅读:
    暑假第二十七测
    暑假第二十七测
    【真题解】牛宫
    【伪题解】牛宫
    最优贸易
    跳马问题
    求和问题
    【题解】山区建小学
    OpenStack之虚机冷迁移代码简析
    OpenStack之虚机热迁移代码解析
  • 原文地址:https://www.cnblogs.com/wangsicongde/p/7576890.html
Copyright © 2011-2022 走看看