CF58E 题解

难得有一道一次交就过的紫题,发现只有一篇题解,就来一篇。

解法是可行性剪枝的 dfs 。

\(c = 0\) 时,显然我们只需要把 \(c\) 的最高位处理成 \(a+b+jw\) 就可以了。

\(a,b,c\) 的个位相等时,根据乘法分配律我们需要处理下一位,注意这时位数需要加一。

对于其他情况,\(a,b,c\) 中两项不变,枚举变的那一项,注意这时需要记录 \(now\) 进行剪枝。

最后注意输入和输出用 scanfprintf 会比字符串拆分的代码短很多(但是我一开始写的是 string (

还有,预处理高位并存储在数组里会方便许多,不要学习我写了一半才想到预处理。

AC 代码:

// jaco2567 AK IOI
// #include <bits/stdc++.h>
#include <queue>
#include <stack>
#include <cmath>
#include <string>
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

inline int read() {
    int res = 0, F = 1;
    char k;
    while (!isdigit(k = getchar())) if (k == '-') F = -1;
    while (isdigit(k)) {
	  	res = res * 10 + k - '0';
        k = getchar();
    }
    return res * F;
}

inline void write(int x) {
    if (x < 0) {
		putchar('-');
		x = -x;
	}
	if (x > 9) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}

const int INF = 0x3f3f3f3f;

long long a, b, c, asa, asb, asc;
long long p[20];
int ans = INF;

void dfs(long long a, long long b, long long c, long long jw, long long na, 
	long long nb, long long nc, int now, int deep) {

	if (now >= ans) return;

	if (a == 0 && b == 0 && c == 0 && jw == 0) {
		// 没有需要加的数了 = 找到答案
		ans = now; asa = na; asb = nb; asc = nc;
		return ;
	}

	if (c == 0) { // 把 c 补上欠的数
		long long res = a + b + jw;
		int tmp = 0;
		while (res != 0) { tmp++; res /= 10; }

		dfs(0, 0, 0, 0, na + p[deep] * a, nb + p[deep] * b, 
			nc + p[deep] * (a + b + jw), now + tmp, deep + 1);
		
		return ;
	}

	if ((a + b + jw) % 10 == c % 10) { // 个位相等,处理高位

		dfs(a / 10, b / 10, c / 10, (a % 10 + b % 10 + jw) / 10, na + (a % 10) * p[deep], 
			nb + (b % 10) * p[deep], nc + (c % 10) * p[deep], now, deep + 1);
		
		return ;
	}

	dfs(a * 10 + (c % 10 - b % 10 - jw + 10) % 10, b, c, jw, na, nb, nc, now + 1, deep); // 加 a
	dfs(a, b * 10 + (c % 10 - a % 10 - jw + 10) % 10, c, jw, na, nb, nc, now + 1, deep); // 加 b
	dfs(a, b, c * 10 + (a % 10 + b % 10 + jw) % 10, jw, na, nb, nc, now + 1, deep); // 加 c
}

int main() {
	scanf("%lld+%lld=%lld", &a, &b, &c);

	p[0] = 1;
	for (int i = 1; i <= 18; i++) {
		p[i] = p[i-1] * 10;
	}

	dfs(a, b, c, 0, 0, 0, 0, 0, 0);

	printf("%lld+%lld=%lld", asa, asb, asc);

	return 0;
}

posted @ 2021-08-06 12:05  MilkyCoffee  阅读(62)  评论(1)    收藏  举报