公式修正
题目描述
给出一个算术公式,形式为A*B=C("表示乘法)。但是该公式可能存在错误,你需要用替换字符的方式进行修正(不可以移动)。请问最少替换多少个字符可以使得原公式成立。 替换一个字符指的是将原公式中某个位置的字符用另外的0~9的字符代替。注意你不能替换公式中的’*’和’=’符号;同时替换后的式子中所有数字都不能包含前导零。
输入描述
第一行包含一个整数T,表示共有多少组测试用例1≤T≤100)。
接下来T 行每包含一个字符串S,表示给定的公式,其一定是A*B=C的格式 保证公式中的A、B、C一定是正整数,并且不含前导零。字符串 S 的长度不超过10。
输出
输出 T行,每行一个整数表示最少要替换多少个字符可以使得公式成立。
如果无论如何都不能使得等式成立则输出-1。
样例1
输入
2
12*12=444
123*123=1
输出
1 -1
解释:
对于第一个测试数据,你只需要替换一个字符,将’4’替换成’1’,即得到12*12=144。
对于第二个测试数据,无法通过替换得到合法的公式。
样例2
输入
1
1*123=123
输出
0
解释:
无需替换,公式本身就是正确的
思路分析
这道题不能想得太复杂,比如S1是4位数,S2是3位数,遍历所有四位数S1(1000-9999),遍历所有三位数S2(100-999),对于每一组S1和S2有唯一确定的S3,进行判断就差不多能过了。
需要注意的就是特殊情况的判断,主要是1*123=8
,不是-1而是2,因为可以转为0*123=0
。题目要求说的是公式中的A、B、C一定是正整数,但字符换完以后没说不能是0,所以要考虑换成0的情况。
if (n3 == 1 && (n1 == 1 || n2 == 1)) { // 只有一位,乘数和积都是一位的情况,如果另一位不是1位,则可以变成0*123=0,是2
if ((n1 == 1 && n2 != 1) || (n1 != 1 && n2 == 1)) {
list.add(2);
continue;
}
}
其次就是位数不满足的情况:
if (n3 < n1 + n2 - 1 || n3 > n1 + n2) { // 位数超出限制,是-1
list.add(-1);
continue;
}
参考代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = in.nextInt();
in.nextLine();
String[][] arr = new String[T][3];
for (int i = 0; i < T; i++) {
String str = in.nextLine();
String[] str1 = str.split("\\*"); // 直接按"*"分割不行,需要加上\\
String str2 = str1[1];
String[] str3 = str2.split("\\=");
arr[i][0] = str1[0];
arr[i][1] = str3[0];
arr[i][2] = str3[1];
}
List<Integer> list = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
int n1 = arr[i][0].length();
int n2 = arr[i][1].length();
int n3 = arr[i][2].length();
int res = Integer.MAX_VALUE;
int A = Integer.parseInt(arr[i][0]);
int B = Integer.parseInt(arr[i][1]);
int C = Integer.parseInt(arr[i][2]);
if (n3 == 1 && (n1 == 1 || n2 == 1)) { // 只有一位,乘数和积都是一位的情况,如果另一位不是1位,则可以变成0*123=0,是2
if ((n1 == 1 && n2 != 1) || (n1 != 1 && n2 == 1)) {
list.add(2);
continue;
}
}
if (n3 < n1 + n2 - 1 || n3 > n1 + n2) { // 位数超出限制,是-1
list.add(-1);
continue;
}
int t1 = (int) Math.pow(10, n1);
int t2 = (int) Math.pow(10, n2);
for (int j = (int) Math.pow(10, n1 - 1); j < t1; j++) { // 遍历该位数最小值到最大值,如3位数从100到999
for (int k = (int) Math.pow(10, n2 - 1); k < t2; k++) {
int p = j * k;
if (help1(p) == n3) {
res = Math.min(res, help2(A, j) + help2(B, k) + help2(C, p));
}
}
}
list.add(res);
}
for (int i = 0; i < list.size(); i++) {
if (i == list.size() - 1) {
System.out.println(list.get(i));
} else {
System.out.print(list.get(i) + " ");
}
}
}
public static int help1(int x) {
int r = 0;
while(x != 0) {
r++;
x /= 10;
}
return r;
}
public static int help2(int A, int B) {
int r = 0;
String a = String.valueOf(A);
String b = String.valueOf(B);
for (int i = 0; i < a.length(); i++) {
if (a.charAt(i) != b.charAt(i)) {
r++;
}
}
return r;
}
}