• 京东2016实习生编程题—生日礼物


    在赛码网上看到的2016年的京东实习生在线编程题,赛码网上将其难度划为最高之一,于是就做了一下。

    赛码网不让转载题目,原题目在这:http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3816&konwledgeId=41

    整体思路与hashmap的思路有点类似,

    每一个信封都是一个Entry类,

    它内部还包含它的下一个最优Entry(保持嵌套信封数最多)。

    内部还包含了所有比他大的信封entry所组成的arraylist(利用这些entry来计算出哪一个装此entry可达到嵌套数最多)

    /**
     * Created by CLY on 2017年4月23日.
     */
    package pers.cly.algorithm.birthday_gift;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.Scanner;
    
    public class Main {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            while (scanner.hasNext()) {
                int line_num = scanner.nextInt();
                long card_x_size= scanner.nextLong();
                int card_y_size = scanner.nextInt();
                
                ArrayList<Entry> sumList = new ArrayList<>();
                for (int i = 0; i < line_num; i++) {
                    long now_x = scanner.nextLong();
                    int now_y = scanner.nextInt();
                    //信封必须大于卡片
                    if (now_x>card_x_size&&now_y>card_y_size) {
                        Entry now_entry = new Entry();
                        now_entry.set_index(i+1);
                        now_entry.set_mailer_x_size(now_x);
                        now_entry.set_mailer_y_size(now_y);
                        sumList.add(now_entry);
                        
                        //将当前entry与以存的entry进行大小的比较
                        for(Entry old_entry :sumList){
                            long old_x = old_entry.get_mailer_x_size();
                            int old_y = old_entry.get_mailer_y_size();
                            if (old_x>now_x&&old_y>now_y) {//旧信封比当前信封大
                                now_entry.get_more_big_entry().add(old_entry);
                            }else if (now_x>old_x&&now_y>old_y) {//当前信封比旧信封大
                                old_entry.get_more_big_entry().add(now_entry);
                            }
                        }
                    }
                }
                
                Entry start_mail=null;
                int sum = 0;
                //如果有比信件大的信封
                if (sumList.size()>=1) {
                    Iterator<Entry> iterator = sumList.iterator();
                    //先计算第一个entry的最优嵌套数,然后再和其他entry的最优嵌套数比对
                    do {
                        Entry now_entry = iterator.next();
                        
                        int now_len = now_entry.get_best_len();
                        
                        if (now_len!=0) {//拥有最优嵌套数
                            if (now_len>sum) {
                                sum = now_len;
                                start_mail = now_entry;
                            }
                        }else {//还未计算最优嵌套数,现在计算
                            now_len = calculate_best_len(now_entry);
                            if (now_len>sum) {
                                sum = now_len;
                                start_mail = now_entry;
                            }
                        }
                    } while (iterator.hasNext());
                    
                    System.out.println(sum);
                    System.out.print(start_mail.get_index()+" ");
                    Entry next_entry = start_mail.get_best_choose();
                    while (next_entry!=null) {
                        System.out.print(next_entry.get_index()+" ");
                        next_entry = next_entry.get_best_choose();
                    }
                }else {//没有合适的信封
                    System.out.println(sum);
                }
            }
        }
        /**
         * 计算某entry的最优嵌套数
         * @param arrayList
         * @return 最优嵌套数
         */
        private static int calculate_best_len(Entry target_entry) {
            ArrayList<Entry> arrayList = target_entry.get_more_big_entry();
            int target_best_len=1;
            Entry target_best_choose=null;
            
            //如果target_entry拥有子list(比他大的entry),则迭代找到最大的len
            for (Entry entry : arrayList) {
                int son_best_len = entry.get_best_len();
                
                //如果该子entry也没有最优嵌套数,则先计算他的最优嵌套数
                if (son_best_len==0) {
                    son_best_len = calculate_best_len(entry);
                }
                son_best_len++;//加上本entry后的总嵌套数
                
                if (son_best_len>target_best_len) {
                    target_best_len = son_best_len;
                    target_best_choose = entry;
                }
            }
            
            target_entry.set_best_choose(target_best_choose);
            target_entry.set_best_len(target_best_len);
            
            return target_best_len;
        }
    }
    
    class Entry{
        int index;//是第几个出现的
        long mailer_x_size;
        int mailer_y_size;
        ArrayList<Entry> more_big_entry;
        Entry best_choose;//选择哪一个信封可以达到最多嵌套数
        //当选择了当前卡片后,前套数最多能加几(当前entry如果没有计算过,则为0,计算过后至少为1)
        int best_len;
        
        public Entry() {
            this.index=0;
            this.mailer_x_size=0;
            this.mailer_y_size=0;
            this.best_len = 0;
            this.best_choose = null;
            this.more_big_entry= new ArrayList<>();
        }
        
        public void set_index(int index) {
            this.index=index;
        }
        public void set_mailer_x_size(long mailer_x_size) {
            this.mailer_x_size=mailer_x_size;
        }
        public void set_mailer_y_size(int mailer_y_size) {
            this.mailer_y_size=mailer_y_size;
        }
        public void set_best_choose(Entry entry) {
            this.best_choose = entry;
        }
        public void set_best_len(int best_len) {
            this.best_len = best_len;
        }
        
        public int get_index() {
            return this.index;
        }
        public long get_mailer_x_size() {
            return this.mailer_x_size;
        }
        public int get_mailer_y_size() {
            return this.mailer_y_size;
        }
        public ArrayList<Entry> get_more_big_entry() {
            return this.more_big_entry;
        }
        public Entry get_best_choose() {
            return this.best_choose;
        }
        public int get_best_len() {
            return this.best_len;
        }
    }
  • 相关阅读:
    第一节 49_ref_out 简单
    第一节 38函数 简单
    第二节 2面向对像简介 简单
    第一节 42字符串基础 简单
    第二节 3属性 简单
    第一节 33enum枚举 简单
    Java jdbc 数据库
    css 使IE和FIREFOX下变为手型
    JS调用PageMethods
    USB设备量产导致通用串行总线控制器显示感叹号解决办法
  • 原文地址:https://www.cnblogs.com/red-code/p/6756113.html
Copyright © 2020-2023  润新知