前几天CSDN论坛的首页,看到一则帖子,题目是:“一道经典的C++题,关于分钱的问题,适合新手阅读(黑客X档案论坛题目) ”,链接如下:http://blog.csdn.net/gisfarmer/archive/2009/02/08/3869236.aspx
题如下:
把一张面值为一元的纸币,换成一分,二分,五分的硬币,共有多少种换法?编程输出每一种不同的算法。
这道题很简单,是最简单的C++题,用C也可以做。
看了原贴http://bbs.hackerxfiles.net/thread-98055-15-1.html和http://blog.csdn.net/gisfarmer/archive/2009/02/08/3869236.aspx
里面有很多答案,说实在的,有点看不下去了,因为总感受写的代码有点别扭,做的一些循环都像是写死了的。。
比如:
- int x=0,y=0,z=0,n=0;
- int count=0;
- for(z=1;z<20;z++)
- {
- for(y=1;y<=(100-z*5)/2;y++)
我不知道z<20为什么要这么写,为什么是20呢?
还有就是如果如果再加一个一毛,或者是五毛,求共有多少种换法,这又怎么写呢?
又或者是分的不是一块钱,分的是五块钱,求共有多少种换法,又怎么写呢?
。。。哎,我也是写程序的,很怕业务的改变,所以在想,能不能写一个通用点的方法,于是自己写了一个如下,还请路过的指教一下(本人是菜鸟).
写了两个方法,一个需要输出明细,一个不需要输出明细,大家可以试着玩一下。。
c#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleStudy
{
class SumNumberDemo
{
static void Main() {
Console.WriteLine("SumNumberDemo");
List<int> intList = new List<int>();
string reString =string.Empty;
int count = 0;
intList.Add(1);
intList.Add(2);
intList.Add(5);
//intList.Add(7);
//intList.Add(9);
//不需要输出明细
SplitMoney(100, 0, intList, 0, ref count);
//输出明细
//SplitMoney(10, 0, intList, 0, reString, ref count);
Console.WriteLine(string.Format("总共有{0}种分法",count));
}
/// <summary>
/// 分钱方法
/// </summary>
/// <param name="pmMoney">被分的钱</param>
/// <param name="pmMoneyNow">当前分法的钱的和</param>
/// <param name="pmMoneyList">分钱列表</param>
/// <param name="pmMoneyIndex">当前分钱索引</param>
/// <param name="pmString">当前分法明细</param>
/// <param name="pmSplitCount">分钱方法总数统计</param>
static void SplitMoney(int pmMoney, int pmMoneyNow, List<int> pmMoneyList, int pmMoneyIndex, string pmString, ref int pmSplitCount)
{
int snCount=pmMoneyList.Count;
if (pmMoneyIndex < pmMoneyList.Count)
{
for (int i = 0; i * pmMoneyList[pmMoneyIndex] <= pmMoney; i++)
{
//当前和统计
int snSumNow = i * pmMoneyList[pmMoneyIndex]+pmMoneyNow;
//--begin----这个字符串主要是为了输出的,如果不要求输出可以注释掉----------------
string snString = string.Empty;
if (string.IsNullOrEmpty(pmString))
{
snString = string.Format("{0}*{1}",i, pmMoneyList[pmMoneyIndex]);
}
else {
snString = string.Format("{0}+{1}*{2}", pmString, i, pmMoneyList[pmMoneyIndex]);
}
//---end------------------
if (snSumNow == pmMoney)
{
//------begin-------------
for (int j = pmMoneyIndex+1; j < snCount;j++ )
{
snString += string.Format("+0*{0}", pmMoneyList[j]);
}
//-------end-------------
pmSplitCount++;
Console.WriteLine(string.Format("---{0}={1}---",snString,pmMoney));
}
else
{
SplitMoney(pmMoney, snSumNow, pmMoneyList, pmMoneyIndex + 1, snString, ref pmSplitCount);
}
}
}
}
/// <summary>
/// 分钱方法
/// </summary>
/// <param name="pmMoney">被分的钱</param>
/// <param name="pmNoneyNow">当前分法的钱的和</param>
/// <param name="pmMoneyList">分钱列表</param>
/// <param name="pmMoneyIndex">当前分钱索引</param>
/// <param name="pmSplitCount">分钱方法总数统计</param>
static void SplitMoney(int pmMoney, int pmNoneyNow, List<int> pmMoneyList, int pmMoneyIndex, ref int pmSplitCount)
{
int snCount = pmMoneyList.Count;
if (pmMoneyIndex < pmMoneyList.Count)
{
for (int i = 0; i * pmMoneyList[pmMoneyIndex] <= pmMoney; i++)
{
//当前和统计
int snSumNow = i * pmMoneyList[pmMoneyIndex] + pmNoneyNow;
if (snSumNow == pmMoney)
{
pmSplitCount++;
}
else
{
SplitMoney(pmMoney, snSumNow, pmMoneyList, pmMoneyIndex + 1, ref pmSplitCount);
}
}
}
}
}
}