题解 P1874 【快速求和】
暴力深搜
关键是此题数据不用剪枝......
咳咳咳,这道题我采用的是回溯,回溯的内容是1~K个加号的组合。
一旦有情况的值==n,即可输出i。
重要内容请看代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<string>
using namespace std;
string st;
long long n,i;
long long book[55];
bool f;
void dfs(long long k)//明明是组合,却被我写成了排列
{
if(k==i)
{//重点啊重点啊(敲黑板)
long long ans=0,sum=st[0]-'0';//sum开始不为0,就使得一开始就有+号的情况能正好避免。
for(int j=1;j<st.size();j++)
{
if(book[j]==0)sum=sum*10+st[j]-'0';//进位就不用我讲了吧
else ans+=sum,sum=st[j]-'0';//ans累计这一段的和,而这时正好所对应的那个数字,sum就不用清零,直接等于那个数字。
}
ans+=sum;//最后没有加号,就要把最后一个加数加上。
if(ans==n)f=true;
return ;
}
for(int j=1;j<st.size();j++)
{
if(book[j]==0)
{
book[j]=1;
dfs(k+1);
book[j]=0;
}
}
}
int main()
{
cin>>st>>n;
for(i=0;i<st.size();i++)//要从0开始,可能正好这个字符串就是那个数字本身呢?(这里有10分)
{
memset(book,0,sizeof(book));
f=false;
dfs(0);//从0开始,就可满足字符串就是数字本身的情况。
if(f==true)
{
cout<<i<<endl;//题目要求最少加号,所以一旦找到一个能使字符串变成n的,就可以输出了。
return 0;
}
}
cout<<-1<<endl;//别忘了输出-1(这里又有10分)
return 0;
}
嗯,可能是应为本蒟蒻的语言组织能力不好,怕在座的各位同学听不懂,于是就有了下面的配图: 希望能对同学们理解本蒟蒻的程序有所帮助!