【ProjectEuler】ProjectEuler_032

// 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
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值