题目描述:

标题
构造表达式类别
综合时间限制
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

整体思路:

可将‘+’,‘-’,以及‘ ’ 分别用mode的三个值0、1、2来代表。故建立数组mode[],用来存储每两位整数之间的运算。

此时可将整数部分(num)和插入的运算符号(mode)看做互相独立的两个部分。

因此,要遍历不同运算模式,只需将数组mode[]的值做遍历,每次再根据对应的mode组合对整数做运算即可。

遍历思路:

在此参照for循环原理,联想到x进制数进位的规则,因此,可将遍历三种模式在各位上的不同组合的这一多层嵌套循环结构,看成三进制数的进位

因此可写出遍历函数cycle()

int cycle(int * mode, int n)
{int i, SUM = 0;n = n - 2; //调整下标优先适合mode[]数组while(mode[0] < 3){/*对mode数组最后一位递增循环,并在每次循环组成新mode序列时计算表达式数值当mode[n]递增至3时,向前位进一并重置末位mode[n]*/for(mode[n] = 0; mode[n] < 3; mode[n]++){SUM += compute(mode, n);}//进位操作for(i = n; i >= 0; i--){if(mode[i] == 3){mode[i] = 0;mode[i-1]++;//若最高位进至3,则已经完成遍历,跳出循环if(mode[0] == 3)break;}else break;}}return (SUM);
}

有了遍历函数,就只需再写出整数按照遍历过程中每次形成的mode组合进行运算的函数compute()

计算思路:

计算思路本身并不复杂,只需分'+''-'和' '三种情况,依次对相邻整数操作即可。但实际编写过程中,实现' '即前后数字组合成新数这一算法出现了很多之前意想不到的错误和漏洞,如:前卫数字结合到了后位上时,原位置前的运算操作如何继承?若数字从后位开始向前结合,前位数字需要乘以10的次方数需要额外代码确定(即算出已经结合部分的位数),导致复杂化等等的问题。

因此,考虑在对NUM按mode进行其他运算之前,先查找出mode[2](即' ',结合)运算,并将需要结合的数字结合到位置靠前的那项上,以解决上述运算操作继承问题,同时,将以被结合的数字清为0,保证它们不会影响运算。

之后,就只需考虑'+''-'两种运算,遇到结合运算直接跳过即可。因此可以写出compute()函数:

int compute(int *mode, int n)
{int sum, i, temp;int NUM[most] = {0};//用NUM数组拷贝num数组for(i = 0; i <= n + 1; i++){NUM[i] = num[i];}for(i = 0; i <= n; i++){//' ',即结合运算if(mode[i] == 2){int I = i;//记录下需要结合的第一项的位置while(mode[i] == 2){NUM[I] = NUM[I] * 10 + NUM[i+1];NUM[i+1] = 0;i++;}}}for(i = 0, sum = NUM[0]; i <= n; i++){if(mode[i] == 0)sum += NUM[i+1];else if(mode[i] == 1)sum -= NUM[i+1];else if(mode[i] == 2)continue;}if(sum == 0)return 1;else return 0;
}

到此,已经可以写出完整的代码:

#include <stdio.h>
#include <math.h>int cycle(int * mode, int n);
int compute(int *mode, int n);#define most 9
int num[most] = {0};int main()
{int i, n, SUM;scanf("%d", &n);int mode[9] = {0};for(i = 0; i < most; i++){num[i] = i + 1;}SUM = cycle(mode, n);printf("%d", SUM);return 0;
}int cycle(int * mode, int n)
{int i, SUM = 0;n = n - 2; //调整下标优先适合mode[]数组while(mode[0] < 3){/*对mode数组最后一位递增循环,并在每次循环组成新mode序列时计算表达式数值当mode[n]递增至3时,向前位进一并重置末位mode[n]*/for(mode[n] = 0; mode[n] < 3; mode[n]++){SUM += compute(mode, n);}//进位操作for(i = n; i >= 0; i--){if(mode[i] == 3){mode[i] = 0;mode[i-1]++;//若最高位进至3,则已经完成遍历,跳出循环if(mode[0] == 3)break;}else break;}}return (SUM);
}int compute(int *mode, int n)
{int sum, i, temp;int NUM[most] = {0};//用NUM数组拷贝num数组for(i = 0; i <= n + 1; i++){NUM[i] = num[i];}for(i = 0; i <= n; i++){//' ',即结合运算if(mode[i] == 2){int I = i;//记录下需要结合的第一项的位置while(mode[i] == 2){NUM[I] = NUM[I] * 10 + NUM[i+1];NUM[i+1] = 0;i++;}}}for(i = 0, sum = NUM[0]; i <= n; i++){if(mode[i] == 0)sum += NUM[i+1];else if(mode[i] == 1)sum -= NUM[i+1];else if(mode[i] == 2)continue;}if(sum == 0)return 1;else return 0;
}

以上仅为个人作为初学者的一些思考和理解,如有谬误或更加优秀的解法还请不吝赐教!:)

XDOJ.172 构造表达式相关推荐

  1. #XDOJ 172 构造表达式

    先贴一下问题 构造表达式 类别 综合 时间限制 1S 内存限制 100Kb 问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入'+','-',' ' 构造 ...

  2. 成绩处理C语言xdoj,xdoj五星题172 构造表达式(递归思路)

    xdoj五星题172 构造表达式 标题 构造表达式 类别 综合 时间限制 1S 内存限制 100Kb 问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入' ...

  3. XDOJ-172构造表达式

    标题 构造表达式类别 综合时间限制 1S内存限制 100Kb问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入'+','-',' '构造表达式,插入' ' ...

  4. 【XDOJ】五星级题目--构造表达式之思路分享

    [XDOJ]五星级题目–构造表达式之思路分享 题目: 构造表达式 问题描述 给定一个表示序列长度的整数n(3<=n<=9).在序列1 2 3-n中插入'+','-',' '构造表达式,插入 ...

  5. XDOJ 172-构造表达式

    这个题作为oj上少有的五星题,难倒了大部分同学(包括我),好几次都是这做,但是总不能全对,我又在网上找了些大佬的经验,经过大佬的指导,我这才写完,总之就是函数递归的运用,好啦废话到此为止. 问题描述  ...

  6. c语言后缀表达式构造二叉树,C ++程序为后缀表达式构造表达式树

    表达式树基本上是用于表示表达式的二叉树.在表达式树中,节点对应于运算符,每个叶节点对应于操作数.这是一个C ++程序,用于按顺序,前顺序和后顺序遍历为后缀表达式构造一个表达式树. 算法Begin Fu ...

  7. python构造一个二叉树_二叉树-链表存储,用二叉树构造表达式(Python实现)

    既然用到二叉树了,直观上链表的方式比较容易接受,下面用python实现简单的二叉树.二叉树是递归结构,Python的list也是递归结构,基于list类型很容易实现二叉树: 下面是函数 def bin ...

  8. mysql构造函数_MySQL行构造器表达式优化(Row Constructor Expression)

    mysql 官方文档行构造器表达式优化(Row Constructor Expression Optimization)这一节里面,对行构造表达式及其优化进行了介绍,因为用的不多,也没太关注过.但是看 ...

  9. Lambda 表达式(=):网络摘抄,自学用,侵删。

    Lambda 表达式 Lambda 表达式"是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型. 所有 Lambda 表达式都使用 Lambda 运算符 => ...

最新文章

  1. android 上传到了maven,但是报错找不到jar
  2. java websocket修改为同步_初级Java程序员需要掌握哪些主流技术才能拿25K?
  3. App设计灵感之十二组精美的外卖App设计案例
  4. FFLIB网络框架单线程0.0.1版本-epoll_socket
  5. 【优化预测】基于matlab麻雀算法优化BP神经网络预测【含Matlab源码 F002期】
  6. 图像同态滤波 python实现_8图像增强
  7. 计算机控制系统模型,控制系统数学模型及其类型-电脑自学网
  8. cad设计师证书怎么考
  9. jink下载出现:Failed to download RAMCode . Failed to prepare for programming .
  10. matlab求合同矩阵,matlab-线性代数 判断 合同矩阵
  11. java费切罗_细数目前主流的十二个自行车种类
  12. EasyExcel使用教程
  13. Qt 实现带阴影 无边框的QMessageBox
  14. 智能小车制作过程(今日笔记+)
  15. 文献精读(1)MRD,NSCLC
  16. JPG图片上传在IE下的问题
  17. vcf、plink文件格式互转
  18. 数字图像处理(图像增强)——拉普拉斯算子
  19. 和数集团:什么是区块链技术?
  20. noip模拟 马云 Mr_H

热门文章

  1. Zigbee协调器主动使终端节点退网
  2. python+selenium爬虫,使用selenium爬取热门微博数据
  3. canvas太极八卦图
  4. 广州大学数据库实验报告_广州大学学生实验报告.doc
  5. table属于html标记吗,table标签是什么意思
  6. CSS设置下划线与文字间距距离
  7. C语言链表超简单教程
  8. SQL语句在dos操作MySQL数据库
  9. MVC---Android App的设计架构:MVC,MVP,MVVM与架构经验谈
  10. SQL server中如何设置外键