此题来自牛客网-字节跳动2017后端工程师实习生笔试题
题目
-
题目:
有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大? -
输入描述:
每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。 -
输出描述:
输出一个数,表示最大和是多少。 -
示例1:
-
输入:
2 ABC BCA
-
输出:
1875
-
题解
-
解析:
// 第一步 ABC=100×A+10×B+C BCA=100×B+10×C+A ABC+BCA=110×B+101×A+11×C 要使和最大,则权值越大的映射的数字应越大 所以:B为9;A为8;C为7 // 第二步 需要判断权重为0的是否为头字母,如果是0,则和权值为1的替换;若1也不满足,则继续向上替换(类似冒泡)
-
解答:
import java.util.Comparator; import java.util.Scanner; import java.util.Arrays; import java.lang.Math; public class Main{ public static void main(String[] args){ // 1/输入 Scanner sc = new Scanner(System.in); int n = sc.nextInt(); String[] strs = new String[n]; for(int i=0; i<n; i++){ strs[i] = sc.next(); } // 2/计算出现次数 和 首字母 Element[] chs = new Element[10]; for (int i = 0; i < 10; i++) { // 注意需要初始化 chs[i] = new Element(); } for(int i=0; i<n; i++){ int len = strs[i].length(); char c = strs[i].charAt(0); chs[strs[i].charAt(0) - 'A'].flagHeadCh = true; // 是否为首字母 for(int j=0; j<len; j++){ chs[strs[i].charAt(j) - 'A'].times += (int)Math.pow(10,len-j-1); // 计算出现次数 } } // 3/排序(从大到小) Arrays.sort(chs, new Comparator<Element>() { @Override public int compare(Element e1, Element e2) { return e1.times < e2.times ? 1 : (e1.times == e2.times ? 0 : -1); } } ); // 4/赋权值 for(int i=0; i<10; i++){ chs[i].weight = 9-i; } // 5/调整权值,使首字母不为0 for(int i=9; i>0; i--){ // 类似于冒泡排序 if(chs[i].flagHeadCh){ chs[i].weight = chs[i-1].weight; chs[i-1].weight = 0; }else{ break; } } // 5/根据权值,计算和 int sum = 0; for(int i=0; i<10; i++){ sum += chs[i].weight * chs[i].times; } System.out.println(sum); } static class Element { long times; //出现次数 boolean flagHeadCh; //是否为首字母,即权值是否可以为0 int weight; //权值 } }
注意事项
- Scanner
如果使用sc.nextLine();
需要注意使用完sc.nextInt()后还需要再加一个sc.nextLine();,使其换行
或者使用sc.next();
- 新建的类,注意在使用前需要new
- 排序
// 正序
int[] array = {10, 3, 6, 1, 4, 5, 9};
Arrays.sort(array);
// 逆序
Integer[] arr = {9, 8, 7, 2, 3, 4, 1, 0, 6, 5};
Arrays.sort(arr, Collections.reverseOrder()); // 注意这里要是类,不能是基本数据类型,可转换为数据包装类
int[] arr2 = Arrays.stream(arr).mapToInt(Integer::valueOf).toArray();
// Comparable方式:在实体中实现Comparable<实体>接口,重写compareTo方法
public class Student implements Comparable<Student> {
private String name;
private Integer age;
public int compareTo(StudentAsc o) {
if(null == this.age) {
return -1;
}
if(null == o.getAge()) {
return 1;
}
return this.age.compareTo(o.getAge());
}
}
// Comparator方式:使用Collections.sort(List list, Comparator<? super T> c)
Collections.sort(students, new Comparator<Student>() {
public int compare(Student o1, Student o2) {
if(null == o1.getAge()) {
return -1;
}
if(null == o2.getAge()) {
return 1;
}
return o1.getAge().compareTo(o2.getAge());
}
});