题目地址
AC代码
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
int mark[1000010];
int ans[6];
long long int numA,numB;
void dfs(int *list,string obj,int size,int now,int before,int num){
list[now]=num;
long long int sum=0,temp=obj[0]-'0';
for (int i = 1; i < size; ++i) {
if(list[i]==list[i-1]){
temp*=10;
temp+=obj[i]-'0';
}else{
sum+=temp;
temp=obj[i]-'0';
}
if(i==size-1)sum+=temp;
}
if(sum<=numA&&sum>=numB){
numB = sum;
mark[numB]++;
memcpy(ans,list, sizeof(ans));
}
if(now!=size-1)dfs(list,obj,size,size-1,now,num+1);
if(now!=before+1)dfs(list,obj,size,now-1,before,num);
list[now]=num-1;
if(before == 0&&now==size-1){
sum=0,temp=obj[0]-'0';
for (int i = 1; i < size; ++i) {
if(list[i]==list[i-1]){
temp*=10;
temp+=obj[i]-'0';
}else{
sum+=temp;
temp=obj[i]-'0';
}
if(i==size-1)sum+=temp;
}
if(sum<=numA&&sum>=numB){
numB = sum;
mark[numB]++;
memcpy(ans,list, sizeof(ans));
}
}
}
int main() {
ios::sync_with_stdio(false);
string a,b;
while(cin>>a>>b,a!="0"&&b!="0"){
if(a==b||a.length()>b.length())cout<<b<<" "<<b<<endl;
else if(a.length()<=b.length()){
numA=0,numB=0;
for (int i = 0; i < a.length(); ++i) {
numA*=10;
numA+=a[i]-'0';
}
for (int j = 0; j < b.length(); ++j) {
numB+=b[j]-'0';
}
if(numA<numB){
cout<<"error"<<endl;
continue;
}
if(b.size()==1){
cout<<b<<" "<<b<<endl;
continue;
}
int list[6];
for (int k = 0; k < 6; ++k) {
list[k]=1;
}
numB=1;
memset(mark,0, sizeof(mark));
dfs(list,b,b.length(),b.length()-1,0,2);
if(mark[numB]!=1)cout<<"rejected"<<endl;
else{
cout<<numB<<' '<<b[0];
for (int i = 1; i < b.size(); ++i) {
if(ans[i]!=ans[i-1])cout<<' ';
cout<<b[i];
}
cout<<' '<<endl;
}
}
}
return 0;
}
题解和题目思路
这道题被放到了剪枝里面去,但是仔细想想,搜索的规模也不大,直接DFS过去也不是问题。
我将要处理的字符串中的元素进行分类,初始情况为全部都为一类(不切),拿123456这个字符串举例,初始情况为111111
,然后从最后一位开始,每次DFS都更改其中的一位,分为两种情况:
情况一:更改当前子串当前位下一位的分类,例如
111112
改为111122
情况二:如果当前位不是最后一位,更改新字串中的最后一位为下一类,以上面111122
中的22
为例,将其改为23
然后每一次DFS以后都计算当前分类情况下的数值,观察其是否满足条件并且大于等于当前已有的最大值,如果满足,就记录当前的分类情况至ans[]中以便输出,并且在对应的mark[]处加一以便判断是否存在重复的情况
其中有几种可以特判的情况请注意下,一是A>=B;二是在一的基础上,B的每一位单独加起来都大于A;三是在二的基础上,如果B为个位数则可以直接输出
DFS一定要确保能够搜索到所有的情况,漏了的话很可能导致WA,例如我原来就漏了不切的初始情况(扶额),下次注意