// Problem 32
// 06 December 2002
//
// We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
//
// The product 7254 is unusual, as the identity, 39 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
//
// Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
//
// HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
#include <iostream>
#include <windows.h>
using namespace std;
// 检测某个数是否没有重复的数(1-9全有)
bool CheckHaveAllDigit(int num)
{
bool exsitDigit[9] = {false}; //位bit,用于记录存在的位
int currentDigit = 0;
while(num != 0)
{
currentDigit = num % 10;
if(currentDigit == 0) //含0,不符合要求
{
return false;
}
if(exsitDigit[currentDigit - 1]) //已存在这个数字
{
return false;
}
exsitDigit[currentDigit - 1] = true; //记录
num /= 10;
}
return true;
}
// 求num的exponent次幂
int pow(int num, int exponent)
{
for(int i = 1; i < exponent; i++)
{
num *= num;
}
return num;
}
int sum = 0; //记录所有符合的结果的和
bool results[10000] = {false};
void ProgressMutipliers(int mutipliers)
{
if(!CheckHaveAllDigit(mutipliers)) //不符合要求
{
return;
}
int mutiplier1 = 0; //乘数
int mutiplier2 = 0; //被乘数
int product = 0; //结果
for(int mutiplierBit1 = 1; mutiplierBit1 <= 4; mutiplierBit1++) //乘数的位数
{
//mutipliers=mutiplier2连接mutiplier1
mutiplier1 = mutipliers % pow(10, mutiplierBit1);
mutiplier2 = mutipliers / pow(10, mutiplierBit1);
product = mutiplier1 * mutiplier2;
if(product > 9999) //排除大于9999的数,因为结果只能是4位
{
continue;
}
if(CheckHaveAllDigit(mutipliers * 10000 + product))
{
cout << mutiplier1 << " * " << mutiplier2 << " = " << product;
if(!results[product]) //表明不存在
{
results[product] = true;
sum += product;
cout << endl;
}
else
{
cout << "\t已存在" << endl;
}
}
}
}
// 令乘数和被乘数的位数分别为x,y,则结果的位数为x+y或者x+y-1(基本推断)
// 根据题意,x+y+x+y=9或者x+y+x+y-1=9
// 但x+y!=4.5(必须是整数),所以排除第一种情况,所以x+y=5,结果为4位,这是这个题的一个隐藏条件
void F1()
{
cout << "void F1()" << endl;
LARGE_INTEGER timeStart, timeEnd, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&timeStart);
const int MAX_MULTIPLIERS = 98765; //乘数和被乘数从左至右组合写起来最大的数
const int MIN_MULTIPLIERS = 12345; //乘数和被乘数从左至右组合写起来最小的数
for(int i = MIN_MULTIPLIERS; i <= MAX_MULTIPLIERS; i++)
{
ProgressMutipliers(i);
}
cout << "符合条件的数的和为" << sum << endl;
QueryPerformanceCounter(&timeEnd);
cout << "Total Milliseconds is " << (double)((double)(timeEnd.QuadPart - timeStart.QuadPart) * 1000 / (double)freq.QuadPart) << endl;
}
//主函数
int main()
{
F1();
return 0;
}
/*
void F1()
42 * 138 = 5796
28 * 157 = 4396
48 * 159 = 7632
4 * 1738 = 6952
39 * 186 = 7254
4 * 1963 = 7852
27 * 198 = 5346
18 * 297 = 5346 已存在
1738 * 4 = 6952 已存在
1963 * 4 = 7852 已存在
12 * 483 = 5796 已存在
符合条件的数的和为45228
Total Milliseconds is 85.2839
By GodMoon
2011年11月4日12:22:01
*/
【ProjectEuler】ProjectEuler_032
最新推荐文章于 2024-08-04 14:55:04 发布