问题描述
* 有 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;
}
}