最大映射

问题描述

* 有 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;
    }
}


原文地址:https://www.cnblogs.com/dogeLife/p/10855257.html