XDOJ 构造表达式 C

前言

日精进。

初次尝试自底而上的编程思路。(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

 


解析

重要因素

  1. 自底向上,功能与函数对应:取数字,取运算符,计算,罗列运算符的不同组合,输入输出
  2. 递归实现运算符的3^(n-1)种情况
  3. 运算符的不同组合需有数组op[9]存储(数组长度为9:n<=9,op<=8,字符串结束标志"\0")

重点关注的细节

  1. 数组下标 idx ,运算符op[idx] 左右两侧数字分别为 idx+1, idx+2 (idx从0起)
  2. 哪些变量需要定义为全局变量
  3. 循环
  4. 各函数的返回值类型 以及 参数表

解答

#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博客_自顶向下和自底向上的基本思想

分治算法(自顶而下,逐步求精)

经典算法思想2——分治(Divide-and-Conquer) - 知乎 (zhihu.com)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值