题目描述
有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?
输入描述
每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。
输出描述
输出一个数,表示最大和是多少。
输入示例
2
ABC
BCA
输出示例
1875
解题思路
- 为所有的英文字母根据位置先后赋予权重,再加起来,方便后面根据排序。若在个位,则权重为 1,若在十位,则权重为 10,百位则 100,以此类推。
- 根据排序的字母的权重,从 9 开始与权重相乘,再到 8,以此类推,最终获得结果。
- 注意不要让 0 出现在最前面,可以存储在集合中,检查字符串的头部是否会出现 0(当出现了 10 个不同的字符时,权重最小的那个字符就会是 0)。
Java代码实现
import java.util.Scanner;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int len = in.nextInt(); // 接收的行数
String[] array = new String[len]; // 接收的所有字符串
for (int i = 0; i < len; ++i) {
array[i] = in.next();
}
long[] weight = getWeight(); // 预先计算权重,减少每次实时计算的开销
System.out.println(getSum(weight, array)); // 得出结果
}
private static long[] getWeight() {
// 因为最多有 12 位字母,所以权重也有 12 位
// 权重从左到右依次为 {1 * 10 ^ 11, 1 * 10 ^ 10, ..., 1}
long[] weight = new long[12];
long priority = 1;
weight[11] = 1;
for (int i = 10; i >= 0; --i) {
priority *= 10;
weight[i] = priority;
}
return weight;
}
private static long getSum(long[] weight, String[] array) {
HashSet<Character> head = new HashSet<Character>(); // 记录所有字符串的第一个字符,防止第一个字符数字为 0
HashMap<Character, Long> map = new HashMap<Character, Long>(); // 字符-权重映射表
for (int i = 0; i < array.length; ++i) {
head.add(array[i].charAt(0)); // 记录第一个字符
int charLen = array[i].length(); // 当前字符串长度
int temp = 12;
for (int j = charLen - 1; j >= 0; --j) { // 从最后往前遍历字符
char curChar = array[i].charAt(j); // 当前字符
long curWeight = weight[--temp]; // 当前权重
if (map.containsKey(curChar)) {
curWeight += map.get(curChar);
}
map.put(curChar, curWeight);
}
}
// 接下来按照权重对映射表进行排序
ArrayList<Map.Entry<Character, Long>> list = new ArrayList<>(map.entrySet());
Collections.sort(list, new Comparator<Map.Entry<Character, Long>>(){
public int compare(Map.Entry<Character, Long> o1, Map.Entry<Character, Long> o2) {
return o1.getValue() > o2.getValue() ? -1 : 1;
}
});
// 如果出现了 10 个字母,那么说明必定会有 1 个字母是 0,防止这个字母出现在字符串最前面
if (list.size() == 10) {
int index = 9;
while (head.contains(list.get(index).getKey())) { // 如果他在字符串最前面,就找一个没有在最前面出现过的字符放在 0 这个位置,而且尽量选择权重小的字符
--index;
}
list.remove(index); // 删除了,相当于这个权重乘以 0
}
long sum = 0;
int temp = 9;
for (Map.Entry<Character, Long> entry : list) {
sum += entry.getValue() * temp;
--temp;
}
return sum;
}
} 
京公网安备 11010502036488号