最大映射
问题描述
* 有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。
* 现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。
* 这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。
* 现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?
输入描述
* 每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n ,
* 接下来有 n 行,每行一个长度不超过 10 且仅包含大写字母 A-J 的字符串。
* n 不大于 50,且至少存在一个字符不是任何字符串的首字母。
唯一要求
* 这些整数必须是正整数且它们的字符串不能有前导零,也就是字符串在映射完成之后 不能存在以0开头的整形数字。
* 这点要求其实加大了难度
解题思路
-
字母映射,要综合所有输入字符串,找出最大的映射规则,要让最后得到的映射数字之和最大
那就对所有字母分别计算其权重值,按照每个字母权重大小进行数字的映射。
-
结果用什么类型进行保存呢? 50行,每行10个字母。按照最大值估计,一个数99亿,50个加起来5000亿,
这远远超过了32位int型的范围了( -2^31——2^31-1,即-2147483648——2147483647。正负二十二亿之内)
所以果断采用Long型(-9223372036854774808~9223372036854774807)保存结果。
-
深入思考一下,结果需要我们输出最大映射之和的值,并没有要求输出最大映射规则,因为对每一组输入,都有不同的映射规则
说明我们一定可以采取某种方法,不将映射规则详细列出,只需要将最后的最大映射之和计算出来即可。
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; } }