一道经典的C++题,关于分钱的问题,适合新手阅读,黑客X档案论坛题目 [c#]

前几天CSDN论坛的首页,看到一则帖子,题目是:“一道经典的C++题,关于分钱的问题,适合新手阅读(黑客X档案论坛题目) ”,链接如下:http://blog.csdn.net/gisfarmer/archive/2009/02/08/3869236.aspx

题如下:

把一张面值为一元的纸币,换成一分,二分,五分的硬币,共有多少种换法?编程输出每一种不同的算法。

这道题很简单,是最简单的C++题,用C也可以做。

看了原贴http://bbs.hackerxfiles.net/thread-98055-15-1.htmlhttp://blog.csdn.net/gisfarmer/archive/2009/02/08/3869236.aspx

里面有很多答案,说实在的,有点看不下去了,因为总感受写的代码有点别扭,做的一些循环都像是写死了的。。

比如:

  1. int x=0,y=0,z=0,n=0;
  2. int count=0;
  3. for(z=1;z<20;z++)
  4. {
  5. 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);

}

}

}

}

}

}