华为机试4.27:公式修正

公式修正
题目描述

给出一个算术公式,形式为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;
    }
}
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值