8-1 回溯法实验报告 (15 分)(思路+详解)
一:题目
给定k个正整数,用算术运算符+,-,,/ 将这k个正整数连接起来,是最终的得数恰为m。
如果有多组满足要求的表达式,只要输出一组,每一步算式用分号隔开。
如果无法得到m,得输出“No Solution”。
样例输入:d
5 125
7 2 2 12 3
第一行输入整数的个数k和m,
第二行输入k个整数。
这只是其中一种结果
样例输出: 73=21 21*12=252 252-2=250 250/2=125
二:思路:
1.排列树 + 子集树
2.我们穷举所有的可能的数字组合,这是全排列,但要注意的是在全排列中,如果给出的数据有重复的数字,那么我们求的全排列后的数据是有重复的,所以我们要进行去重处理;
3.得到全排列的结果后,我们要对每一个全排列的结果进行子集树处理,因为每一次往下递归都是’+’,’-’,’*’,’/’;,递归的终止条件就是当我们统计 sum == M时候,或者是我们的操作符个数满足要求的时候,如果仅仅是操作符满足个数是不统计操作符的结果的;
二:上码
/*
1.题目:
给定k个正整数,用算术运算符+,-,*,/ 将这k个正整数连接起来,是最终的得数恰为m。
如果有多组满足要求的表达式,只要输出一组,每一步算式用分号隔开。
如果无法得到m,得输出“No Solution”。
样例输入:
5 125
7 2 2 12 3
第一行输入整数的个数k和m,
第二行输入k个整数。
样例输出: 7*3=21 21*12=252 252-2=250 250/2=1252.思路分析:
从输出的样例顺序(7,3,12,2,2)可以得知,这是一种全排列后的结果,对于每组数据之间的加减乘除,我们
可以做子集树划分 */#include<bits/stdc++.h>
using namespace std;int N,M;
int cnt = 0;
vector<vector<int> >ans1;
vector<int> path1;vector<vector<char> >ans2;
vector<char> path2;//求出数字的全排列组合
void backtacking1(int N,vector<int>& vec,vector<bool>& vis){if(path1.size() == N){ans1.push_back(path1);return;}for(int i = 0; i < N; i++){if(vis[i] == true) continue;vis[i] = true;path1.push_back(vec[i]);backtacking1(N,vec,vis);path1.pop_back();vis[i] = false;}
}//子集树的排列
//横向的for循环为加减乘除,纵向的为一种全排列的结果
void backtacking2(vector<char>& v1,vector<int>& v2,int sum,int index){if(sum == M || path2.size() == N - 1){ //这里递归结束的条件为满足 M时 if(sum == M){ //还有的是操作符号的个数不能大于 N - 1个 ans2.push_back(path2);cnt = 1;}return ; }for(int i = 0; i < 4; i++){//这里小于4是有4个操作符 char ch = v1[i];if(ch == '+'){sum = sum + v2[index];}else if(ch == '-'){sum = sum - v2[index];}else if(ch == '*'){sum = sum * v2[index];}else if(ch == '/'){sum = sum / v2[index];}index++;//表示纵向的一种全排列结果集的下标 path2.push_back(ch);//将符号存进去 backtacking2(v1,v2,sum,index);//这里的顺序不能乱 path2.pop_back();index--;if(ch == '+'){sum = sum - v2[index];}else if(ch == '-'){sum = sum + v2[index];}else if(ch == '*'){sum = sum / v2[index];}else if(ch == '/'){sum = sum * v2[index];} }
} //验证全排列
void text01(){ for(int i = 0; i < ans1.size(); i++){for(int j = 0; j < N; j++){cout << ans1[i][j] << " ";}cout << endl;}
}int main(){vector<int>v1;//输入的数据vector<vector<int> >v3;//记录可行解 vector<char> operators(4); set<int>s[100]; set<int>:: iterator st;cin >> N >> M;for(int i = 0; i < N; i++){int num;cin >> num;v1.push_back(num);}cout << endl; vector<bool> vis(N,false); backtacking1(N,v1,vis); operators[0] = '+';operators[1] = '-';operators[2] = '*';operators[3] = '/';for(int i = 0; i < ans1.size(); i++){vector<int> v2;int count = 0; for(int j = 0; j < N; j++){ v2.push_back(ans1[i][j]);if(ans1[i-1][j] == ans1[i][j] && i != 0){count++; } }if(count == N){ // 这是为了去重的,因为在全排列中,如果有重复的元素,那么最终输出 continue; //的结果是有重复的组数据的 }int num = v2[0];backtacking2(operators,v2,num,1);if(cnt == 1){//这里存的是满足条件的 数字组合 v3.push_back(v2);} cnt = 0;}for(int i = 0; i < ans2.size(); i++){//v3.size() 和ans2.size()大小是一致的 cout << "操作数为:";for(int j = 0; j < N; j++){cout << v3[i][j] << ' ';}cout << endl;cout << "操作符为:"; for(int j = 0; j < N - 1; j++){//N个数需要 N-1个操作符 cout << ans2[i][j] << ' ';}cout << endl;}} //5 125
//7 3 12 2 2//5 125
//7 2 2 12 3
下方的的数据按照操作符都可以得到正确结果
8-1 回溯法实验报告 (15 分)(思路+详解)相关推荐
- 7-11 租用游艇问题 (15 分)(思路+详解+一步步分析+网格解决动态规划问题)Come boy!!!!
一:题目 题目来源:王晓东,<算法设计与分析> 长江游艇俱乐部在长江上设置了n个游艇出租站1,2,-,n.游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇.游艇出租站i ...
- 算法分析与设计——回溯法实验报告
算法导论 课程设计 成 绩 题 目: 回 溯 法 学院班级: 1613013 学 号: 16130130216 姓 ...
- php生成迷宫图片,PHP实现基于回溯法求解迷宫问题的方法详解
本文实例讲述了PHP实现基于回溯法求解迷宫问题的方法.分享给大家供大家参考,具体如下: 引言 最近在leetcode上看了些算法题,有些看着很简单的很常用的东西,竟然一下子想不出来怎么求解,比如说:实 ...
- 7-43 字符串关键字的散列映射 (25 分)(思路+详解+不懂的兄弟们来呀)兄弟们我干了5个小时,一个一个测试点过的
一:题目 7-43 字符串关键字的散列映射 (25 分) 给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数H(Key)将关键字Key中的最后3个字符映射为整数,每个字符占5位 ...
- 10-4 6-4 查询厂商“D“生产的PC和便携式电脑的平均价格 (10 分)思路+详解+测试用例
前言:测试用表 贴心杰将这个测试表分享给大家 ,如果大家做题的时候发现那个点过不去,一定不要直接看别人的博客,先自己测试用例,如果思路也对 ,验证数据也对,还有错误 你再看看别人的思路!!! CREA ...
- 7-8 数字三角形 (31 分)(思路+详解+动态规划)Come Baby!!!!!!!!!!!
一:题目 观察下面的数字金字塔.写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以从当前点走到左下方的点也可以到达右下方的点. 在上面的样例中,从13到8到26到15到2 ...
- 7-1 矩阵链相乘问题 (20 分)(思路+详解+题目解析) 动态规划做法
一:题目: 输入样例: 在这里给出一组输入.例如: 5 30 35 15 5 10 20 输出样例: 在这里给出相应的输出.例如: 11875 二:基本解析 1.基本的动态规划知识: 1):求解过程是 ...
- 7-45 航空公司VIP客户查询 (25 分)(思路+详解+map用法解释+超时解决)兄弟们来呀冲压呀呀呀呀
一:题目 不少航空公司都会提供优惠的会员服务,当某顾客飞行里程累积达到一定数量后,可以使用里程积分直接兑换奖励机票或奖励升舱等服务.现给定某航空公司全体会员的飞行记录,要求实现根据身份证号码快速查询会 ...
- 7-21 求前缀表达式的值 (25 分)(思路详解)
一:题目 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4.请设 ...
最新文章
- 最快捷的PPT技能提升之路 PPT定制 驼峰设计
- Git 分布式版本管理
- XidianOJ 1176 ship
- ASP.NET Core 2.2+Quartz.Net 实现Web定时任务
- 电话光端机安装步骤详解
- csdn上传图片发现:缺少图像源文件地址
- Fluent API — 流畅API(基于Java介绍)
- 诡异奇怪的“虚拟硬盘可用空间不足”告警
- SwipeListView 详解 实现微信,QQ等滑动删除效果
- 文档智能理解:通用文档预训练模型与数据集
- bzoj 1786 bzoj 1831: [Ahoi2008]Pair 配对(DP)
- Mirth Connect 第一章 快速安装
- R语言ggplot2绘图
- dnf时装补丁教程_dnf时装补丁怎么用?DNF时装补丁教程
- 海盗湾(The Pirate Bay)的战争——每一名技术人员都应该思考的问题
- 不惧年龄,无限可能,32岁也能成功转行IT行业
- 关于安装不上tesseract和opencv以及稀里糊涂的解决方案
- webpack性能优化全方案
- linux上java项目链接不上mysql,本地测试无问题
- 牛顿迭代法leetcode