思路:题目要求在顾客花掉手中所有n元钱的情况下能够买到最少的商品数,这句话包含2层意思,一是顾客必须正好花掉手中的n元钱,二是在正好花掉手中n元钱的情况下,顾客可能有多种消费方案,要求从这些方案中找出最少商品的方案。解决此题的一种思路如下(以题目中所给示例1为例):
1、 先对商品价格a[a_size]={1、3、4、5}按照降序排列,排序后即为price[a_size]={5、4、3、1};
2、 以顾客手中的总钱数b=7,去依次除商品价格price[a_size],以下标i=0开始,如果不够整除,则说明用户手中的钱数b不够买该价格的商品,则对商品价格数组下标i进行加1操作,直到能够整除为止,得到的整数div即为买得价格为price[i]的商品的个数(本例中总钱数能够整除商品价格price[0]=5,div=1,说明顾客能够买到1件价格为5的商品),然后以手中的钱数b=7对该商品价格进行取余操作,即得顾客手中剩余的钱b(本例中b=b%price[0]=7%5=2),如果取余得0,说明用户正好花完手中的钱,该方案为一种有效的方案。否则对商品价格下标i进行加1操作,重复上述过程(本例中为i=1,此时price[1]=4, div=b/price[1]=2/4=0不能整除,说明买不到价格为4的商品,继续i++,i=2,此时price[2]=3,div=b/price[1]=2/3=0仍旧不能整除,继续i++,此时i=3,price[3]=1,div=b/price[3]=2/1=2,说明可以买2件价格为1的商品,此时手中还剩b=b%price[3]=0,说明为一种有效消费方案。)。之所以对价格进行降序排列,是因为题目中要求能够买到最少的商品数。
3、 对所有消费方案进行比较,找出买得商品数最少的方案。
4、 按照输入的商品价格顺序,依次给出各商品所买的个数。
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int comparator ( const void * elem1, const void * elem2 ); // 比较函数
int caculate(int a_size, int* a, int b, int** result); //
int main(int argc, char* argv[])
{
int a_size = 4;
int a[4] = {2, 3, 4, 5};
int b = 2;
int **result = new int*;
*result = new int[a_size];
int i=0;
caculate(4, a, b, result);
system("pause");
return 0;
}
int caculate(int a_size, int* a, int b, int** result)
{
int i=0, j=0;
int *Price = new int[a_size]; // 保存各个商品价格
int nMoney = b; // 总钱数
int **k = new int*[a_size]; // 统计各方案
bool *valid = new bool[a_size]; // 各方案的有效性
for(i=0; i<a_size; i++)
{
k[i] = new int[a_size];
memset(k[i], 0, a_size*sizeof(int));
valid[i] = false;
}
int validNum = 0; // 统计有效方案个数
int GoodsNum = 0; // 所买商品数
int Min = 2^32-2; // 所买商品数最小值
int Min_Num = -1; // 所买商品数最小值所对应的方案号
int div = 0; // 取整
int rem = 0; // 取余
memset(*result, 0, a_size*sizeof(int));
// 1、拷贝各商品价格
memcpy(Price, a, a_size*sizeof(int));
// 2、对价格按从大到小进行排序
qsort(Price, a_size, sizeof(int), comparator);
// 3、计算所买商品的各种方案
for(j=0; j<a_size; j++) // j: 方案号
{
for(i=j; i<a_size; i++) //
{
div = nMoney/Price[i];
if( div == 0)
{
continue;
}
else
{
k[j][i] = div;
nMoney %= Price[i];
if(0 == nMoney) // 该方案有效,置方案有效标志
{
valid[j] = true;
validNum++;
break;
}
}
}
nMoney = b;
}
// 4、比较各方案,给出最优方案号Min_Num
if(0 != validNum)
{
for(i=0; i<a_size; i++)
{
if(valid[i])
{
for(j=0; j<a_size; j++)
GoodsNum += k[i][j];
if(GoodsNum < Min)
{
Min = GoodsNum;
Min_Num = i;
}
}
GoodsNum = 0;
}
// 5、按输入顺序输出
for(i=0; i<a_size; i++)
{
for(j=0; j<a_size; j++)
{
if(Price[i] == a[j])
{
(*result)[j] = k[Min_Num][i];
break;
}
}
}
for(i=0; i<a_size; i++)
printf("%d ", (*result)[i]);
printf("\n");
}
else
{
printf("%d\n", 0);
}
return 0;
}
// 从大到小排列
int comparator ( const void * elem1, const void * elem2 )
{
return (*(int *)elem2 - *(int*)elem1);
}
不知道大家可有更好的想法解决此问题,欢迎大家过来交流哦~~