首页 > 其他分享 >P1874 快速求和

P1874 快速求和

时间:2022-10-13 20:36:13浏览次数:34  
标签:P1874 求和 sum int step 加号 ans now 快速

image

快速求和

题目描述

给定一个数字字符串,用最小次数的加法让字符串等于一个给定的目标数字。每次加法就是在字符串的某个位置插入一个加号。在里面要的所有加号都插入后,就像做普通加法那样来求值。

例如,考虑字符串12,做 \(0\) 次加法,我们得到数字 \(12\)。如果插入 \(1\) 个加号,我们得到 \(3\),因此,这个例子中,最少用 \(1\) 次加法就得到数字 \(3\)。

再举一例,考虑字符串303和目标数字 \(6\),最佳方法不是3+0+3。而是3+03。能这样做是因为一个数的前导 \(0\) 不会改变它的大小。

输入格式

第一行:一个字符串 \(s\)。

第二行:一个整数 \(n\)。

输出格式

一行一个整数表示最少的加法次数让 \(s\) 等于 \(n\)。如果怎么做都不能让 \(s\) 等于 \(n\) ,则输出 \(-1\)。

样例 #1

样例输入 #1

99999
45

样例输出 #1

4

提示

数据规模与约定

对于 \(100\%\) 的数据,保证 \(1\le \operatorname{len}(s)\le40\),\(1 \leq n\le10^5\)。

解析

这道题的解析好像也没啥可说的,就是爆搜+剪枝就可以过了,读入时将字符转化为数值方便处理,搜索时有两种情况,在该位置加上加号和不加加号,不断向下搜。

代码

#include <bits/stdc++.h>
using namespace std;
string s;
int a[50], res = 0x3f3f3f3f, len, n;
void dfs(int step, int ans, int sum, int now) {
//step表示当前处理的位数,ans是加号数
//sum是最后一个加号前的总和,now表示还在累加的值(加号还未确定) 
	if (ans > res || sum > n || now > n) return ;//剪枝 
	if (step > len) {
		if (sum + now == n) res = ans;//更新答案 
		return ;
	}
	now = 10 * now + a[step];
	dfs(step + 1, ans + 1, sum + now, 0);//添一个加号 
	dfs(step + 1, ans, sum, now);//不添加号 
}
int main() {
	cin >> s >> n; 
	len = s.length();//字符串长度 
	for (int i = 1; i <= len; i ++) a[i] = s[i - 1] - '0';//取出每一位,转成数值 
	dfs(1, 0, 0, 0);//从第一位开始搜索 
	if (res >= len) cout << -1 << '\n';
	else cout << res << '\n';
	return 0;
}

image

标签:P1874,求和,sum,int,step,加号,ans,now,快速
From: https://www.cnblogs.com/YHxo/p/16789530.html

相关文章