#XDOJ 172 构造表达式
先贴一下问题
构造表达式
类别
综合
时间限制
1S
内存限制
100Kb
问题描述
给定一个表示序列长度的整数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
思路:(尤里卡!)提取字符串中的数字是简单的,而且恰好可以和“ ”运算有很好的相性
所以我们使用DFS(一种基础的遍历算法)求出所有可能的字符串,再编写一个子函数来求出字符串的值
——————————————————————————————————
想直接看答案的可以直接滚动到底部♪(´▽`)
——————————————————————————————————
下面是分步思路;
//全局变量
char funstr[128];//用于储存运算式
int cont;//用于储存符合要求的算式数量
int len;//funstr中用于定位的“指针”,我还是喜欢用整形记录啊ψ(`∇´)ψvoid dfs(int i){if(i==n+1){//这个地方还有一行代码,不过为了逻辑性,先不写int tsum=strsum(cfunstr);if(tsum==0)cont++;return ;}//先填数字,再填运算 funstr[len++]=i+'0';if(i<n){funstr[len++]='+';//+运算 dfs(i+1);len--; //复位 funstr[len++]='-';//减运算 dfs(i+1);len--; dfs(i+1); //‘’运算 len--;}else{funstr[len]=0;dfs(i+1);//结尾也要递归到下一层!因为那里才是终点! len--;//这个也不能忘! }return ;
}
然后,我们处理字符串的值,即写出strsum;
为了逻辑清晰,我还写了两个子函数getnum,getfun
前者用于获得字符串中第一个数字,然后把该数字变为‘*’(为了下一次读取到下一个数字);
后者用于获得字符串中第一个计算符号,然后把该符号变为‘*’(为了下一次读取到下一个符号);
这里,我们注意到改变了原字符串的值,所以我们应该备份一下funstr[],备份出来为cfunstr[];
即是在上一个代码块的第8行处加上strcpy(cfunstr,funstr);
int strsum(void){int sum=getnum(cfunstr);
r: switch(getfun(cfunstr)){case 1:sum+=getnum(cfunstr);goto r;break;case -1:sum-=getnum(cfunstr);goto r;break;case 0:printf("%d\n",sum);//这里的printf只是为了方便检查,在最后的代码中删掉了return sum;}
}
int getfun(char *str){int j=0;while(1){switch(str[j]){case '+':printf(" + ");str[j]='*';return 1;case '-':printf(" - ");str[j]='*';return -1;case 0:printf(" | ");//结束的标志return 0;}j++; }
}
int getnum(char *a){int buffer=0,j=0;bool inum=false;while(1){if(a[j]>='0'&&a[j]&&a[j]<='9'){inum=true;buffer=10*buffer+a[j]-'0';a[j]='*';//将数字变为特殊字符,改变结构,所以需要备份}else if(inum&&(a[j]>'9'||a[j]<'0')){printf("%d ",buffer);return buffer;}j++; }
}
以上,这个问题的主要结构就写完了,出了DFS的编写比较难想以外,其他都是基础操作;
下面是全部代码:
#include <stdio.h>
#include <string.h>
int n,cont,len;
char funstr[128];
char cfunstr[128];
int getnum(char *str);
int getfun(char *str);
int strsum(void);
void dfs(int i);
//diver
int main(){scanf("%d",&n);dfs(1);printf("%d",cont);return 0;
}
int getnum(char *a){int buffer=0,j=0;bool inum=false;while(1){if(a[j]>='0'&&a[j]&&a[j]<='9'){inum=true;buffer=10*buffer+a[j]-'0';a[j]='*';//将数字变为特殊字符,改变结构,所以需要备份}else if(inum&&(a[j]>'9'||a[j]<'0'))return buffer;j++; }
}int getfun(char *str){int j=0;while(1){switch(str[j]){case '+':str[j]='*';return 1;case '-':str[j]='*';return -1;case 0:return 0;}j++; }
}int strsum(void){int sum=getnum(cfunstr);
r: switch(getfun(cfunstr)){case 1:sum+=getnum(cfunstr);goto r;break;case -1: sum-=getnum(cfunstr);goto r;break;case 0: return sum;}
}void dfs(int i){if(i==n+1){strcpy(cfunstr,funstr);int tsum=strsum();if(tsum==0)cont++;return ;}//先填数字,再填运算 funstr[len++]=i+'0';if(i<n){funstr[len++]='+';//+运算 dfs(i+1);len--; //复位 funstr[len++]='-';//减运算 dfs(i+1);len--; dfs(i+1); //‘’运算 len--;}else{funstr[len]=0;dfs(i+1);//结尾也要递归到下一层!因为那里才是终点! len--;//这个也不能忘! }return ;
}
以上。
嘛~肯定还有很多方法,不过我觉得这种靠字符串的特性进行运算的方式很巧妙。你说DFS时间复杂度太高?足足O(3^n)?还好题目只限定到n=9(●'◡'●),对计算机来说,洒洒水啦~
也欢迎读读我的其他文章~就在左边的栏目里哦。都是XDOJ里我觉得很有价值的题目。
同时,也欢迎各位指正和优化,互相学习,共同进步!ψ(`∇´)ψ
----西部电子仁儿
初:23/1/29
改:23/2/7
#XDOJ 172 构造表达式相关推荐
- XDOJ.172 构造表达式
题目描述: 标题 构造表达式类别 综合时间限制 1S内存限制 100Kb问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入'+','-',' '构造表达式 ...
- 成绩处理C语言xdoj,xdoj五星题172 构造表达式(递归思路)
xdoj五星题172 构造表达式 标题 构造表达式 类别 综合 时间限制 1S 内存限制 100Kb 问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入' ...
- XDOJ-172构造表达式
标题 构造表达式类别 综合时间限制 1S内存限制 100Kb问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入'+','-',' '构造表达式,插入' ' ...
- 【XDOJ】五星级题目--构造表达式之思路分享
[XDOJ]五星级题目–构造表达式之思路分享 题目: 构造表达式 问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入'+','-',' '构造表达式,插入 ...
- XDOJ 172-构造表达式
这个题作为oj上少有的五星题,难倒了大部分同学(包括我),好几次都是这做,但是总不能全对,我又在网上找了些大佬的经验,经过大佬的指导,我这才写完,总之就是函数递归的运用,好啦废话到此为止. 问题描述 ...
- c语言后缀表达式构造二叉树,C ++程序为后缀表达式构造表达式树
表达式树基本上是用于表示表达式的二叉树.在表达式树中,节点对应于运算符,每个叶节点对应于操作数.这是一个C ++程序,用于按顺序,前顺序和后顺序遍历为后缀表达式构造一个表达式树. 算法Begin Fu ...
- python构造一个二叉树_二叉树-链表存储,用二叉树构造表达式(Python实现)
既然用到二叉树了,直观上链表的方式比较容易接受,下面用python实现简单的二叉树.二叉树是递归结构,Python的list也是递归结构,基于list类型很容易实现二叉树: 下面是函数 def bin ...
- mysql构造函数_MySQL行构造器表达式优化(Row Constructor Expression)
mysql 官方文档行构造器表达式优化(Row Constructor Expression Optimization)这一节里面,对行构造表达式及其优化进行了介绍,因为用的不多,也没太关注过.但是看 ...
- Lambda 表达式(=):网络摘抄,自学用,侵删。
Lambda 表达式 Lambda 表达式"是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型. 所有 Lambda 表达式都使用 Lambda 运算符 => ...
最新文章
- Java中的比较总结
- 学习MongoDB(Troubleshoot Replica Sets) 集群排除故障
- 参数数组长度_JS数组操作方法总结(二)——pop、shift、push、unshift
- 深度案例 | 纷享销客:用户需求精准洞察下的敏捷开发
- [C++][数据结构]栈(stack)的实现
- 求封闭曲线面积vc代码_圆锥曲线综合5个类型,逐一突破
- 美国伊利诺伊大学香槟分校计算机专业,伊利诺伊大学香槟分校计算机科学排名第7(2020年TFE美国排名)...
- Kalman Filter 学习笔记
- Apache服务配置
- CRM管理系统、教育后台、赠品管理、优惠管理、预约管理、试听课、教师、学生、客户、学员、商品管理、科目、优惠券、完课回访、客户管理系统、收费、退费、回访、账号权限、订单流水、审批、转账、rp原型
- 温习ASP调用C#的DLL并实现用户名密码进行域验证反馈结果
- MPLS(多协议标记交换)协议能否降低跨省组建企业专网的成本?
- 【信息系统项目管理师】第3章-项目立项管理 知识点详细整理
- Pycharm专业版注册教程
- vue 一周日历展示,上一周下一周展示。
- win7的附件计算机没了,win7系统附件工具不见了的解决方法
- 20210107WEB渗透学习之信息收集
- 一个短信息运营商SP告诉你手机短信收费黑幕!!
- 获得中国行政区划接口
- 鸿蒙 林蒙 秦羽,从主神归来的主角们