前言
日精进。
初次尝试自底而上的编程思路。(Maybe)
题干
问题描述
给定一个表示序列长度的整数n(3<=n<=9)。在序列1 2 3…n中插入‘+’,‘-’,‘ ’构造表达式,插入‘ ’表示前后两个数字构成一个整数,例如1 2 -3 -4 -5=0。
输出构造的所有表达式中,结果为0的表达式的数量,例如n=3时,只有表达式1+2-3=0,输出结果为1。
输入说明
输入数据为一个整数n(n<10),表示序列长度,同时表示输入序列为“1 2 3…n”。
输出说明
对于每一组数据,输出一个整数,表示构造的表达式中结果为0的表达式数量。
输入样例
3
输出样例
1
解析
重要因素
- 自底向上,功能与函数对应:取数字,取运算符,计算,罗列运算符的不同组合,输入输出
- 递归实现运算符的3^(n-1)种情况
- 运算符的不同组合需有数组op[9]存储(数组长度为9:n<=9,op<=8,字符串结束标志"\0")
重点关注的细节
- 数组下标 idx ,运算符op[idx] 左右两侧数字分别为 idx+1, idx+2 (idx从0起)
- 哪些变量需要定义为全局变量
- 循环
- 各函数的返回值类型 以及 参数表
解答
#include<stdio.h>
int n;
char op[9];
int idx;
int r;
int get_num(){
int num=idx+1;
while(op[idx] == ' ' && idx < n-1){
num=num*10+(idx+2);
idx++;
}
return num;
}
int get_op(){
if(idx >= n-1) return 0;
if(op[idx] == '+'){
idx++;
return 1;
}
if(op[idx] == '-'){
idx++;
return -1;
}
return 0;
}
void calculate(){
int sum=0;
idx=0;
int opp;
sum=get_num();
while(1){
opp=get_op();
if(opp==0){
break;
}
else{
sum=sum+opp*get_num();
}
}
if(0 == sum) r++;
}
void deal(int pos){ // list possibilities
if(pos == n-1){
calculate();
}
else{ // recursion achieves 3^(n-1) possibilities of operators
op[pos]=' ';
deal(pos+1);
op[pos]='+';
deal(pos+1);
op[pos]='-';
deal(pos+1);
}
}
int main(){ // input & output
scanf("%d",&n);
deal(0);
printf("%d",r);
return 0;
}
拓展
本蒟蒻尚未能从0 —> 1,参考:
XDOJ.T172_构造表达式(XDOJ五星级题目之一)_既然来了,请让我无耻地求一波赞QAQ-CSDN博客
自底而上 & 自顶而下
自顶向下与自底向上编程思想的对比_xiaorang的专栏-CSDN博客_自顶向下和自底向上的基本思想