• 最大映射


    问题描述

    * 有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。
    * 现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。
    * 这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。
    * 现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?

    输入描述

    * 每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n ,
    * 接下来有 n 行,每行一个长度不超过 10 且仅包含大写字母 A-J 的字符串。
    * n 不大于 50,且至少存在一个字符不是任何字符串的首字母。

    唯一要求

    * 这些整数必须是正整数且它们的字符串不能有前导零,也就是字符串在映射完成之后 不能存在以0开头的整形数字。
    * 这点要求其实加大了难度

    解题思路

    1. 字母映射,要综合所有输入字符串,找出最大的映射规则,要让最后得到的映射数字之和最大
      那就对所有字母分别计算其权重值,按照每个字母权重大小进行数字的映射。
    2. 结果用什么类型进行保存呢? 50行,每行10个字母。按照最大值估计,一个数99亿,50个加起来5000亿,
      这远远超过了32位int型的范围了( -2^31——2^31-1,即-2147483648——2147483647。正负二十二亿之内)
      所以果断采用Long型(-9223372036854774808~9223372036854774807)保存结果。
    3. 深入思考一下,结果需要我们输出最大映射之和的值,并没有要求输出最大映射规则,因为对每一组输入,都有不同的映射规则
      说明我们一定可以采取某种方法,不将映射规则详细列出,只需要将最后的最大映射之和计算出来即可。
    class Solution{
        public static Long MaxSum(){
            Scanner in = new Scanner(System.in);
            int n = in.nextInt();
    
            // old weight
            long[] array = {0,0,0,0,0,0,0,0,0,0};
            long max = 0L;
    
            // 头部元素
            Set<Character> head = new HashSet<>();
    
            // 按照权重排序后的字母
            Character[] orderedChar = new Character[10];
    
            while(--n>=0){
                String str = in.next();
                head.add(str.charAt(0));
                for(int i=str.length()-1; i>=0; i--) {
                    array[str.charAt(i)-'A'] += Math.pow(10,str.length()-1-i);
                }
            }
    。
            // 省去了字母映射的具体规则
            long[] orderedArray= Arrays.copyOfRange(array,0,array.length);
            sort(orderedArray);
    
            // 根据 old weight 和 有序权重值数组 获得有序字母数组
            for(int i=0;i<10;i++) {
                orderedChar[i] = (char)('A'+(getIndex(array,orderedArray[i])));
            }
            System.out.println("排序后的字母");
            for(Character c:orderedChar) {
                System.out.print(c);
            }
            System.out.println();
    
            // 如果有前零导 则进行替换和移动
            if(head.contains(orderedChar[0])) {
                for(int i=1;i<10;i++) {
                    if(!head.contains(orderedChar[i])) {
                        System.out.println(i);
                        long temp  = orderedArray[i];
                        for(int j=i; j>0; j--) {
                            orderedArray[j] = orderedArray[j-1];
                        }
                        orderedArray[0] = temp;
    //                    orderedArray[0] = orderedArray[i];
    //                    orderedArray[i] = temp;
                       break;
                    }
                }
            }
    
    
            System.out.println("除去前0导后");
            for(long lon:orderedArray) {
                System.out.println(lon);
            }
    
            for(int i=1;i<10;i++){
                max += (orderedArray[i]*i);
            }
    
            return max;
        }
    
        public static int getIndex(long[] array, long target) {
            for(int i=0;i<array.length; i++) {
                if(array[i] == target) {
                    array[i] = 11L;
                    return i;
                }
            }
            return -1;
        }
    }


  • 相关阅读:
    当当网css代码
    当当网代码6
    游戏UI设计(2.1)窗口之父CXWnd的封装
    英语(1)备考——词汇
    UML的五类图(UML笔记)
    Sieve of Eratosthenes[ZT]
    std::map初体验
    “非计算机相关专业”的定义
    英语(1)备考——翻译
    使用回调函数发送自定义“消息”
  • 原文地址:https://www.cnblogs.com/dogeLife/p/10855257.html
Copyright © 2020-2023  润新知