笨拙的手指(暴力枚举)
奶牛贝茜正在学习如何在不同进制之间转换数字。
但是她总是犯错误,因为她无法轻易的用两个前蹄握住笔。
每当贝茜将数字转换为一个新的进制并写下结果时,她总是将其中的某一位数字写错。
例如,如果她将数字 14 转换为二进制数,那么正确的结果应为 1110,但她可能会写下 0110 或 1111。
贝茜不会额外添加或删除数字,但是可能会由于写错数字的原因,写下包含前导 0 的数字。
给定贝茜将数字 N 转换为二进制数字以及三进制数字的结果,请确定 N 的正确初始值(十进制表示)。
输入格式
第一行包含 N 的二进制表示,其中一位是错误的。
第二行包含 N 的三进制表示,其中一位是错误的。
输出格式
输出正确的 N 的值。
数据范围
0≤N≤109,且存在唯一解。
输入样例:
1010
212
输出样例:
14
样例解释
14 在二进制下的正确表示为 1110,在三进制下的正确表示为 112。
解题思路
首先最容易想到的就是枚举,通过HashSet存储数据。
- 列举出N(二进制)变化一位后的十进制,为有限个数,并放入到set集合中。
- 进制转换可以利用一个常用的算法(秦九韶算法),如下
public static int convert(char[] s, int k) {
int res = 0;
for (char ch : s
) {
res = res * k + ch - '0';
}
return res;
}
- 列举出N(三进制)变化一位后的十进制,为有限个数
- 判断set集合中是否包含第二步得出的十进制。即求交集。
代码如下:
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class ClumsyFingers {
public static int convert(char[] s, int k) {
int res = 0;
for (char ch : s
) {
res = res * k + ch - '0';
}
return res;
}
public static void main(String[] args) {
String a, b;
Scanner scanner = new Scanner(System.in);
a = scanner.nextLine();
b = scanner.nextLine();
char[] ach = a.toCharArray();
char[] bch = b.toCharArray();
Set<Integer> set = new HashSet<Integer>();
//枚举a变化后的每一个值,将该值加入到set集合中。
for (int i = 0; i < ach.length; i++) {
ach[i] ^= 1;//1变成0,0变成1.
set.add(convert(ach, 2));
ach[i] ^= 1;//复原
}
//对输入的三进制数进行换位和进制转化并判断
for (int i = 0; i < bch.length; i++) {
char current = bch[i];//临时变量,方便复原
for (int j = 0; j < 3; j++) {
bch[i] = (char) (j + '0');//对三进制可能出错的位进行修改。
if (bch[i] != current) {//判断是否修改
int x = convert(bch, 3);//进制转化
if (set.contains(x)) {
System.out.println(x);
return;
}
}
}
bch[i] = current;//复位
}
}
}