// Combinatoric selections
// Problem 53
// There are exactly ten ways of selecting three from five, 12345:
//
// 123, 124, 125, 134, 135, 145, 234, 235, 245, and 345
//
// In combinatorics, we use the notation, 5C3 = 10.
//
// In general,
//
// nCr = n! / r!(n-r)!
// ,where r n, n! = n(n1)...321, and 0! = 1.
// It is not until n = 23, that a value exceeds one-million: 23C10 = 1144066.
//
// How many, not necessarily distinct, values of nCr, for 1 n 100, are greater than one-million?
//
// 题目53:对于1≤n≤100,C(n,r)有多少超过100万?
// 从五个数12345中选出三个数一共有十种方法:
//
// 123, 124, 125, 134, 135, 145, 234, 235, 245, and 345
//
// 在组合数学中我们用5C3 = 10来表示.
//
// 概括来说:
//
// nCr = n! / r!(n-r)!
// ,其中r n, n! = n(n1)...321, 并且0! = 1.
// n = 23时产生第一个超过一百万的数: 23C10 = 1144066.
//
// 对于nCr, 1 <= n <= 100,有多少超过100万的值?包括重复的在内。
//
#include <iostream>
#include <windows.h>
#include <ctime>
#include <assert.h>
#include <MoonMath.h>
using namespace std;
// 打印时间等相关信息
class DetailPrinter
{
public:
void Start();
void End();
DetailPrinter();
private:
LARGE_INTEGER timeStart;
LARGE_INTEGER timeEnd;
LARGE_INTEGER freq;
};
DetailPrinter::DetailPrinter()
{
QueryPerformanceFrequency(&freq);
}
//************************************
// Method: Start
// Access: public
// Describe: 执行每个方法前调用
// Returns: void
//************************************
void DetailPrinter::Start()
{
QueryPerformanceCounter(&timeStart);
}
//************************************
// Method: End
// Access: public
// Describe: 执行每个方法后调用
// Returns: void
//************************************
void DetailPrinter::End()
{
QueryPerformanceCounter(&timeEnd);
cout << "Total Milliseconds is " << (double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / freq.QuadPart << endl;
const char BEEP_CHAR = '\007';
cout << endl << "By GodMoon" << endl << __TIMESTAMP__ << BEEP_CHAR << endl;
system("pause");
}
/*************************解题开始*********************************/
/*
* 此题因为数字很大,而且只需要比较是否大于1000000,因此采用浮点数做组合的计算结果。
*/
//***********************************
// Method: CombinationDouble
// Access: public
// Describe: 计算组合,返回值为double类型
// Parameter: UINT32 n
// Parameter: UINT32 r
// Returns: double
//************************************
double CombinationDouble(UINT32 n, UINT32 r)
{
// C(n,r)=n!/r!/(n-r)!=(r+1)*(r+2)*...*n/1/2/.../(n-r)
double result=1;
for (UINT32 i=r+1;i<=n;++i)
{
result*=i;
}
UINT32 d=n-r;
for (UINT32 i=2;i<=d;++i)
{
result/=i;
}
return result;
}
void TestFun1()
{
cout << "TestFun1 OK!" << endl;
}
void F1()
{
cout << "void F1()" << endl;
// TestFun1();
DetailPrinter detailPrinter;
detailPrinter.Start();
/*********************************算法开始*******************************/
const UINT32 BEGIN_NUM = 1;
const UINT32 END_NUM = 100;
const UINT32 LIMIT_NUM = 1000000;
UINT32 count = 0;
UINT32 r;
for(UINT32 n = BEGIN_NUM; n <= END_NUM; ++n)
{
for(r = BEGIN_NUM; r <= n; ++r)
{
if(CombinationDouble(n, r) >= LIMIT_NUM)
{
++count;
}
}
}
cout << "n包含于[" << BEGIN_NUM << "," << END_NUM << "],C(n,r)超过" << LIMIT_NUM << "的数一共有" << count << "个" << endl;
/*********************************算法结束*******************************/
detailPrinter.End();
}
//主函数
int main()
{
F1();
return 0;
}
/*
void F1()
n包含于[1,100],C(n,r)超过1000000的数一共有4075个
Total Milliseconds is 13.93
By GodMoon
Fri Apr 5 11:28:00 2013
*/
【ProjectEuler】ProjectEuler_053(对于1≤n≤100,C(n,r)有多少超过100万?)
最新推荐文章于 2024-03-31 13:48:53 发布