编程题
1.
最大映射
有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32M,其他语言64M
输入描述:
每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。
输出描述:
输出一个数,表示最大和是多少。
示例1
输入例子:
2 ABC BCA
输出例子:
1875
- 难点:想到把字符转为数字也具有权重
- 难点:范围太大使用Long或long类型
- 难点:某个字符做为某行的首字符时,即使该字符权重最小,也不能设置为0
- 难点:把map只能根据key排序,要想根据value排序,要转化为List集合。
import java.util.*;
import java.util.stream.*;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
int n = in.nextInt();
in.nextLine();
HashMap<String, Long> map = new HashMap<String, Long>();
String head = "";
for (int i = 0; i < n; i++) {
String line[] = in.nextLine().split("");
long w = 1;
head += line[0];
for (int j = line.length - 1; j >= 0; j--) {
Long value = map.get(line[j]);
if (value == null) {
map.put(line[j], w);
} else {
map.put(line[j], w + value);
}
w *= 10;
}
}
List <Map.Entry<String, Long>> mapToList = map.entrySet().stream().sorted(
Map.Entry.comparingByValue()
).collect(Collectors.toList());
if (map.entrySet().size() == 10) {
long res=0;
int index=-1;
for (int m = 0; m < mapToList.size(); m++) {
if (!head.contains(mapToList.get(m).getKey())) {
index=m;
break;
}
}
int w=9;
for (int m = mapToList.size()-1; m >=0; m--) {
if(m!=index){
res+=(mapToList.get(m).getValue()*w);
w--;
}
}
System.out.println(res);
}else{
long res=0;
int w=9;
for (int m = mapToList.size()-1; m >=0; m--) {
res+=(mapToList.get(m).getValue()*w);
w--;
}
System.out.println(res);
}
}
}