菜鸡刷题记录,大佬轻喷。
题目:
思路:
主要考虑加号的个数以及加号的位置:
针对361,加号可以放的位置只有两个3|6|1,放+或者不放+,总共2^2=4种情况
加号0个,即361
加号1个时,两种情况
3+61
36+1
加号两个时
3+6+1
考虑采用递归的方法求解:
将所给的数字看成字符串,每次求解左边的数字和以及右边的数字和。
代码:
相关参数:
const int MAXN = 24;//字符串的最大长度,其实用不了这么多
char data[MAXN];//存储数字
int n;
将字符串转换为数字的:(head为开始字符的下标,tail为结尾字符的下一个位置)
int get_num(int head,int tail){
int sum=0;
for(int i=head;i<tail;i++){
sum=sum*10+data[i]-'0';
}
return sum;
}
递归的函数:(head为开始字符的下标,tail为结尾字符的下一个位置,len表示当前字符串的长度)
int sum_num(int head,int tail,int len){
if(head+1==tail){
return get_num(head,tail);
}else{
// printf("%d %d %d##\n",head,tail,len);
int sum=get_num(head,tail);
for(int i=head+1;i<tail;i++){
sum+=get_num(head,i)*pow(2,tail-i-1)+sum_num(i,tail,tail-i);
}
return sum;
}
}
当head+1==tail即只有一个字符时,为递归边界,直接返回对应的数字。
其他时候首先sum=整个字符串对应的数字(即加号为0的情况)
然后依次将其分为左右两部分,再求和
关键:
这里左边字符为什么使用get_num(head,i)*pow(2,tail-i-1),而不是继续进行递归,而右边继续进行递归,主要是因为:
第一步:361分解为3和61时,61总共有2^1=2种划分,即单独的{61}以及{6,1},和左边在一起求和时
即:3+61以及3+6+1,3出现了61的划分次数2,即所乘的pow(2,tail-i-1)。
第二步:361分解为36,1时,因为在划分为3,61情况时,已经出现过3,6,1这种情况,为了避免重复出现3,6,1的情况,将36不在进行划分(因为其对应的所有划分情况在上一步已经出现过了),即直接使用get(head,i)
main函数:
int main (){
scanf("%s",data);
n=strlen(data);
printf("%d",sum_num(0,n,n));
return 0;
}