最大映射
有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?输入描述:
每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。输出描述:
输出一个数,表示最大和是多少。输入例子:
2ABC
BCA
输出例子:
1875
思路:开一个map存储字符以及该字符权重,某字符出现在个位权重*1,出现在十位权重*10,以此类推。
则 A 的权重为 100 + 1 = 101
B 的权重为 10 + 100 = 110
C 的权重为 1 + 10 = 11
之后map按value从大到小排序,最大为9,次大为8... 结果为 110*9+101*8+11+7
考虑开头不为0,当存在0值时,从后往前查询map找到第一个不是头的字符,用0代替,该字符原本代表的数字下移给后一个字符,以此类推
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Map.Entry;
public class Main {
// 自定义排序规则。对map按照value递减的顺序排序
public static List<Map.Entry<Character, Long>>
mapSortByValue(Map<Character, Long> map) {
List<Map.Entry<Character, Long>> list =
new ArrayList<Map.Entry<Character, Long>>(map.entrySet());
// 降序排序
Collections.sort(list, new Comparator<Map.Entry<Character, Long>>() {
@Override
public int compare(Entry<Character, Long> o1, Entry<Character, Long> o2) {
return o1.getValue() > o2.getValue() ? -1 : 1;
}
});
return list;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
// map中key为字母,value为计算该key的总权值,累加结果
Map<Character, Long> map = new HashMap<Character, Long>();
// 用于存储首字母集合,,目的为了防止前置0,后面有注释
// 可以使用其他容器如set
List<Character> heads = new ArrayList<Character>();
while (n-- != 0) {
String temp = scanner.next();
int length = temp.length();
for (int i = 0; i < length; i++) {
char t = temp.charAt(i);
if (i == 0) {
heads.add(t);
}
// 使用Long可以判断null,而long不可以。
// map泛型是包装类型
Long score = (Long) map.get(t);
// 如果score为null那么初试score为0L;否则累加
if (score == null) {
score = 0L;
score += (long) Math.pow(10, length - i - 1);
map.put(t, score);
} else {
// Math.pow(10, length - i - 1),根据位数计算权重,下标为0是最高位。
score += (long) Math.pow(10, length - i - 1);
map.put(t, score);
}
}
}
// 计算最终结果
List&l