//参考:http://www.cppblog.com/cuijiaxing/archive/2012/04/15/171448.aspx
#include <iostream>
#include <fstream>
using namespace std;
ifstream ifs;
int coins[6];//各面值硬币数
int count = 0;//需要的最少硬币数
int cost, c[6]={5, 10, 20, 50, 100, 200};//需支付数和硬币面值,以分计算
void getData() //读入数据
{
int flag = 0;
cout << " 5\t10\t20\t50\t100\t200\n";
cout << "输入各种面值的硬币个数:";
for(int i=0; i<6; i++)
{
ifs >> coins[i];
cout << coins[i] << "\t";
}
double costt;
cout << "\n输入付款金额:";
ifs >> costt;
cost = (int)(costt*100);//将输入的钱转为分
cout << cost << endl;
}
int contains(int a) //如果a恰好等于某一硬币面值,返回该硬币面值下标
{
for(int i=0;i<6;i++)
{
if(c[i]==a && coins[i]>0)
return i;
}
return -1;
}
int getBackMin(int k) //返回找的钱数为k,需要最少的硬币数
{
int count = 0;
for(int i = 5;i >=0;--i)
{
count += k /c[i];
k = k % c[i];
}
return count;
}
//检查一个数的后面是否还有硬币,如果没有了,或者余下的硬币的和小于要找的值。那么就只能用当前硬币来计算了
//co 为要找的钱,index为当前硬币下标
int checkLast(int index,int co)
{
int sum = 0;
for(int i =index-1;i >=0;--i )
{
sum += c[i] * coins[i]; //余下的硬币
}
if(co <= sum) //余下的硬币的和大于要找的硬币
return 1;
else
return 0;
}
void getMinCount()
{
for(int i=5; i>=0; i--) //先找面值较大的硬币
{
if(coins[i]>0) //如果硬币数量不为0,则可以用此面值硬币
{
int *cc = new int[i+1];
cc[0]=0;
for(int k=1; k<=i; k++)
{
cc[k]=c[k-1]; //相当于将c[0,i-1]复制到cc[1,i]
}
for(int j=0; j<=i; j++)
{
if(cost >= (c[i]-cc[j])) //如果要找的钱数>=(当前硬币面值-(比当前硬币面值小的硬币||0)),即当前硬币面值可用
{ //比如要找0.55元,2元数量为0,不可用,考察1元,1元-5角=5角<0.55元,1元可用
if(coins[i] >= cost/(c[i]-cc[j])) //如果已有硬币的数量>=?
{
count += cost/(c[i]-cc[j])+1; //总的要找的钱数+=?+1
if(contains(c[i]-cc[j])!=-1) //如果当前硬币面值-比它小的某一硬币面值恰好等于另外某一硬币面值
{
count--; //要找的总硬币数-1
coins[contains(c[i]-cc[j])] -= cost/(c[i]-cc[j]); //另外某一硬币数量 -= ?
cout << " " << cc[j];
}
else //如果当前硬币面值-比它小的某一硬币面值不等于另外某一硬币面值
{
cout << " " << c[i];
cout << " " << cc[j];
coins[i] -= cost/(c[i]-cc[j]);
}
cost = cost % (c[i]-cc[j]); //剩余要找的钱数
if(contains(c[i]) == -1)
break;
}
else //如果已有硬币的数量<?
{
cout << " " << c[i];
count += coins[i]; //总的要找的钱数 += 当前硬币的数量
cost = cost - c[i]*coins[i]; //要找的钱数-已找的钱数
coins[i]=0; //当前硬币数量用光
}
}
}
//剩下的钱不够支付了
if(!checkLast(i,cost))
{
//检查是否可以用当前的币值来支付
int hasLest = cost / c[i] + 1;
if(hasLest <= coins[i])
{
count += hasLest;
count += getBackMin(c[i] * hasLest - cost);
cost = 0;
break;
}
else
break;
}
}
}
if(count==0 || cost!=0)
{
//cout << "impossible" << endl;
}
else
{
cout << "\n最少的硬币数为:" << count << endl;
}
}
int main()
{
ifs.open("硬币找钱.txt");
while(!ifs.eof())
{
count=0;
getData();
cout << "所用到的硬币有:\n";
getMinCount();
}
ifs.close();
return 0;
}
硬币找钱问题2
最新推荐文章于 2024-05-20 20:42:22 发布