蓝桥杯之买商品
来源:互联网 发布:java怎么操作mysql 编辑:程序博客网 时间:2024/04/30 13:23
公司发了某商店的购物券1000元,限定只能购买店中的m种商品。每种商品的价格分别为m1,m2,…,要求程序列出所有的正好能消费完该购物券的不同购物方法。
程序输入:
第一行是一个整数m,代表可购买的商品的种类数。
接下来是m个整数,每个1行,分别代表这m种商品的单价。
程序输出:
第一行是一个整数,表示共有多少种方案
第二行开始,每种方案占1行,表示对每种商品购买的数量,中间用空格分隔。
例如:
输入:
2
200
300
则应输出:
2
2 2
5 0
做这道题有三种
第一种
#include <iostream>using namespace std;int price[100] = {200,300};int num[100];int m = 0;int count = 0;int slove(int money){ if(money>1000) { return 0; } if(money==1000) { count++; for(int i = 0; i < m; i++) { cout << num[i]<<ends; } cout << endl; // return 0; }// 切记不要用这种方法写,会导致重复 for(int i = 0; i < m ; i++) { num[i]++; slove(money+price[i]); num[i]--; } return 0;}int main(){ cin >> m; slove(0);}
总结:这种方法会将有重复如商品1为0 商品2为0 那么2 2就会有六种二叉树,这种方法使用于有序的排列组合
0011 0101 0110 1100 1010 1001
第二种
#include <stdio.h>#define N 20int way[N][N] = {0};int num[N] = {0};int price[N]={0};int count = 0;int n;void buy(int money,int i);void print();int main(){ int i; scanf("%d",&n); for(i = 0;i<n;i++) { scanf("%d",&price[i]); } buy(0,0); print(); return 0;}void buy(int money,int i){ if(money>1000||i>=n) return; if(money==1000) { int i; for(i = 0;i<n;i++) { way[count][i] = num[i]; } count++; } num[i]++; buy(money+price[i],i); num[i]--; i++; num[i]++; buy(money+price[i],i); num[i]--; i--;} void print(){ int i,j; for(i = 0;i<count;i++) { for(j = 0;j<n;j++) { printf("%d ",way[i][j]); } printf("\n"); }}
总结这种方法在所在的分支上只会往靠向右边子树枝递进 使用于无序排序
如0011 之后不会出现 0101 这里的第三个数的0不会出现只会出现1或2(被排除)
第三种(回溯)
#include <iostream>#include <cstring>using namespace std;int num[100] = {0};int price[100] ={0};int count = 0;int m;int check(){ int money = 0; for(int i = 0;i < m; i++) { money += price[i]*num[i]; } return money;}void dfs(){ int k = 0; while(k > -1) { num[k]++; while(check()>1000&&num[k]<1000/price[k]) { num[k]++; } if(check()==1000) { for(int i = 0;i < m; i++) { cout << num[i]<<ends; } cout << endl; } else if(check()<1000&&k<m)//注意这里是m { k++; } else { num[k] = -1; k--; } }}int main(){ memset(num,-1,100); cin >> m; for(int i = 0; i < m; i++) { cin >> price[i]; } dfs(); return 0; }
总结:回溯法进行剪枝功能,所对应的二叉树与前面的不同
这三道题目的图(画的不太好)
这道题只实用于第二个和第三个程序
1 0
- 蓝桥杯之买商品
- 马云:明年可通过阿里巴巴买日本商品
- 一道亚马逊笔试题:给定钱买最少的商品
- 算法设计与分析:第二章 递归 2.2买商品
- 中国商品之殇
- 商城之商品分类
- 商城之商品列表
- 商城之商品分享
- 买元器件之感
- 2016蓝桥杯假期任务之《买不到的数目》
- OpenCart之商品管理教程
- 促销体系之商品预售
- 商城之首页商品分类
- 购物并发之商品库存
- 数据库操作之商品展示
- Android案例之商品展示
- MyCnCart之商品选项功能
- MyCnCart之商品属性组
- 解决FileZilla 连接服务器报错的问题
- 将博客搬至CSDN
- [置顶]配置SpringMVC
- WeUI 应用到网页面中
- CS344 Udacity 答案
- 蓝桥杯之买商品
- 芝麻分从本地mongo中获取有效数据工具
- c——复合类型——struct union 内存对齐
- spring与mybatis三种整合方法
- java语言求最小公倍数和最大公约数的三种算法
- solr集群搭建
- Handler、looper、Message之间的关系?
- 对象池
- 程序员面试金典——解题总结: 9.17中等难题 17.8给定一个整数数组(有正数有负数),找出总和最大的连续数列,并返回总和