购物积分最佳方案

题目要求:
    1、用户在购置网站上有消费积分m,最近网站推出积分换购的活动。换购商品的【种类数是不确定的】,
         如:“李宁双肩包”下架了,但又增加了“香皂”、“牙刷”等。
    2、每种商品换购的次数不限,如:换购“新款毛巾”10条、12条、100条,都可以。
    3、用户积分换购后几乎都会有剩余,找出换购后积分损失最小的前5种组合。

#include <stdio.h>
#define N 10           //添加商品信息时,只需添加后,更改N的值

#结构体的嵌套

struct stru_goods {
	char name[40];//表示商品的名称。
	float price;//表示商品的单价。
	int num_now = 0; //买的当前数,初始值为0
	int num_max = 0; //能买的最大数,先初始化为0
};

struct stru_goods goods[N] =	{
	{"李宁双肩包", 8200},
	{"新款毛巾", 678},
	{"金吉星软包抽纸", 1040},
	{"2018洗车大毛巾", 1250},
	{"小米 移动电源2", 7900},
	{"不锈钢保温杯", 8690},
	{"滋润型护肤脂", 710},
	{"真好芦荟胶", 1900},
	{"维达 手帕纸", 2090},
	{"佳洁士巨人专用", 395}
};

struct stru_choice { //结构体的嵌套
	struct stru_goods goods_[N] = {
		{"李宁双肩包", 8200},
		{"新款毛巾", 678},
		{"金吉星软包抽纸", 1040},
		{"2018洗车大毛巾", 1250},
		{"小米 移动电源2", 7900},
		{"不锈钢保温杯", 8690},
		{"滋润型护肤脂", 710},
		{"真好芦荟胶", 1900},
		{"维达 手帕纸", 2090},
		{"佳洁士巨人专用", 395}
	};//每种选择的每种商品的基本选择情况//先初始化不变的值,即名称和单价
	float consum_credits = 0.0; //每种选择所消耗的积分,初始值为0
};
struct stru_choice choices[5];//定义一个只存储五种选择的结构体

  定义一个choices结构体数组:放置5个最佳选择

#循环的递归

void deal_goods(int i) {  //递归 用于列举出所有可行的搭配 多次调用sum_goods
	struct stru_goods *p;
	p = &goods[i];//每次所指的元素不同

	if (i < N) {
		for (p->num_now = 0; p->num_now <= p->num_max; p->num_now++) { //now在变化
			deal_goods(i + 1);
		}
	} else
		sum_goods();
}

#主要部分 

void sum_goods() { //计算各搭配所用的积分,存入结构体chioces数组,以大换小
	float sum_credits = 0.0;
	struct stru_goods *p;
	p = goods;
	struct stru_choice *tp;//choice结构体数组指针
	///中间变量 用于存储所有选择的各个商品购买数量 下一步:有用—进一步存入sp所指的替换值 无用—第二个sum_goods()中清零
	struct stru_choice *fp;
	struct stru_choice c[1];
	fp = c;
	//
	struct stru_choice *sp;//sp 指向min的指针
	int k = 0;

	while (p < goods + N) {
		sum_credits = sum_credits + p->num_now * p->price;//累加得到现在方案 消耗的积分
		fp->goods_[k].num_now =
		    p->num_now;//将此时的购买数 存入中间变量 下一步:如果有用—进一步存入sp所指的替换值 无用—第二个sum_goods()中清零
		k++;
		p++;
	}
	if (sum_credits <= credits) {//每次都找出最小值
		float min = choices[0].consum_credits;
		for (tp = choices; tp < (choices + 5); tp++) {
			if (tp->consum_credits <= min) {
				min = tp->consum_credits;
				sp = tp;//sp指向此时的tp所指的最小值
			}
		}

		if (sum_credits > min) {//若此时的积分大于最小值—替换、、最终choices数组中为5个消耗积分最多的方案 但还没有排序
			sp->consum_credits = sum_credits;
			for (int k = 0; k < N; k++) {
				sp->goods_[k].num_now = fp->goods_[k].num_now;//商品购买数替换
			}
		}
	}
}

#显示

void print() {
	struct stru_choice *tp;
	int n = 1;
	//中间变量
	struct stru_choice s[1];
	struct stru_choice *sp;
	sp = s;
	冒泡法 排序 替换信息
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 5 - i; j++) {
			for (tp = choices; tp < choices + 5; tp++) {
				if (tp->consum_credits <= (tp + 1)->consum_credits) {
					*sp = *tp;
					*tp = *(tp + 1);
					*(tp + 1) = *sp;
				}
			}
		}
	}
/输出/
	printf("以下为积分损失最小的5种换购方案:\n\n");

	for (tp = choices; tp < (choices + 5); tp++) {
		printf("#—————第%d选择———————————#\n以下商品消耗积分:%0.0f\n商品名称      需积分   换购数量\n—————————————————————\n",
		       n, tp->consum_credits);

		for (int k = 0; k < N; k++) {
			printf("%-15s   %-10.0f    %-2d\n", tp->goods_[k].name, tp->goods_[k].price, tp->goods_[k].num_now);
		}
		n++;
		printf("========================================\n\n");
	}
}

#功能测试

int main() {
	int i;//商品序号
	printf("请输入您所有的积分:");
	scanf("%f", &credits);
	printf("\n===================================\n       您的总积分有%0.0f\n===================================\n\n",
	       credits);
	struct stru_goods *p;
	for (p = goods; p < (goods + N); p++) {
		p->num_max = credits / p->price; //计算可购买的最大数
	}

	deal_goods(0);//函数实现
	print();//显示前五种方案
	return 0;
}

#示例

请输入您所有的积分:5093

===================================
       您的总积分有5093
===================================

以下为积分损失最小的5种换购方案:

#—————第1选择———————————#
以下商品消耗积分:5091
商品名称      需积分   换购数量
—————————————————————
李宁双肩包        8200          0
新款毛巾          678           2
金吉星软包抽纸    1040          0
2018洗车大毛巾    1250          1
小米 移动电源2    7900          0
不锈钢保温杯      8690          0
滋润型护肤脂      710           0
真好芦荟胶        1900          0
维达 手帕纸       2090          1
佳洁士巨人专用    395           1
========================================

#—————第2选择———————————#
以下商品消耗积分:5090
商品名称      需积分   换购数量
—————————————————————
李宁双肩包        8200          0
新款毛巾          678           0
金吉星软包抽纸    1040          0
2018洗车大毛巾    1250          0
小米 移动电源2    7900          0
不锈钢保温杯      8690          0
滋润型护肤脂      710           2
真好芦荟胶        1900          0
维达 手帕纸       2090          1
佳洁士巨人专用    395           4
========================================

#—————第3选择———————————#
以下商品消耗积分:5090
商品名称      需积分   换购数量
—————————————————————
李宁双肩包        8200          0
新款毛巾          678           0
金吉星软包抽纸    1040          1
2018洗车大毛巾    1250          1
小米 移动电源2    7900          0
不锈钢保温杯      8690          0
滋润型护肤脂      710           1
真好芦荟胶        1900          0
维达 手帕纸       2090          1
佳洁士巨人专用    395           0
========================================

#—————第4选择———————————#
以下商品消耗积分:5088
商品名称      需积分   换购数量
—————————————————————
李宁双肩包        8200          0
新款毛巾          678           1
金吉星软包抽纸    1040          0
2018洗车大毛巾    1250          1
小米 移动电源2    7900          0
不锈钢保温杯      8690          0
滋润型护肤脂      710           0
真好芦荟胶        1900          0
维达 手帕纸       2090          0
佳洁士巨人专用    395           8
========================================

#—————第5选择———————————#
以下商品消耗积分:5086
商品名称      需积分   换购数量
—————————————————————
李宁双肩包        8200          0
新款毛巾          678           2
金吉星软包抽纸    1040          1
2018洗车大毛巾    1250          0
小米 移动电源2    7900          0
不锈钢保温杯      8690          0
滋润型护肤脂      710           0
真好芦荟胶        1900          1
维达 手帕纸       2090          0
佳洁士巨人专用    395           2
========================================


--------------------------------
Process exited after 3.644 seconds with return value 0
请按任意键继续. . .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值