Project Euler 32 Pandigital products


题意:找出所有形如 39 × 186 = 7254 这种,由 1 ~ 9,9个数字构成的等式的和,注意相同的积不计算两次

思路:如下面两种方法


方法一:暴力枚举间断点

/*************************************************************************
    > File Name: euler032.cpp
    > Author:    WArobot 
    > Blog:      http://www.cnblogs.com/WArobot/ 
    > Created Time: 2017年05月24日 星期三 20时08分07秒
 ************************************************************************/

#include <stdio.h>
#include <inttypes.h>
#include <set>
#include <algorithm>

int32_t CalNum(int32_t s,int32_t e,int32_t* num){	// 计算[s,e]之间num值
	int32_t sum = 0;
	for(int32_t i = s ; i <= e ; i++)	sum = sum * 10 + num[i];
	return sum;
}
bool check(int32_t x1,int32_t x2,int32_t* num){		// 判断是否符合题意
	int tmp1 = CalNum(0,x1,num) , tmp2 = CalNum(x1+1,x2,num) , tmp3 = CalNum(x2+1,8,num);
	return tmp1 * tmp2 == tmp3;
}
void solve(){
	int32_t num[9] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
	std::set<int32_t> st;							// 采用set去重 
	do{
		for(int32_t i = 0 ; i < 6 ; i++){
			for(int32_t j = i + 1 ; j < 8 ; j++){
				if( check( i , j , num ) ){			// 暴力枚举两个间断点的位置
					st.insert( CalNum( j + 1 , 8 , num ) );
				}
			}
		}
	}while( std::next_permutation( num , num + 9 ) );

	int32_t sum = 0;
	std::set<int32_t>::iterator it;
	for( it = st.begin(); it != st.end() ; it++)	sum += *it;
	printf("%d\n",sum);
}
int main(){
	solve();
	return 0;
}

方法二:暴力枚举出 a 、b ,判断是否符合题意

/*************************************************************************
    > File Name: euler032t2.c
    > Author:    WArobot 
    > Blog:      http://www.cnblogs.com/WArobot/ 
    > Created Time: 2017年06月24日 星期六 21时55分16秒
 ************************************************************************/

#include <stdio.h>
#include <math.h>
#include <inttypes.h>

#define MAX_N 10000000

int32_t canAdd[ MAX_N + 1 ] = {0};

int32_t HowManyDigs(int32_t i , int32_t j) {
	int32_t digs = 0;
	digs += (int32_t)log10( i ) + 1;
	digs += (int32_t)log10( j ) + 1;
	digs += (int32_t)log10( i * j ) + 1;
	return digs;
}
bool AppearOnce(int32_t x , int32_t* num) {
	while(x) {
		if( ( x % 10 == 0 ) || ( num[  x % 10 - 1 ] ) )	return false;
		num[ x % 10 - 1 ] = 1;
		x /= 10;
	}
	return true;
}
bool IsDigital(int32_t a , int32_t b) {
	int32_t num[9] = {0};
	bool ok = true;
	ok = ( ok && AppearOnce(a,num) );
	ok = ( ok && AppearOnce(b,num) );
	ok = ( ok && AppearOnce(a*b,num) );
	return ok;
}
void solve() {
	int32_t sum = 0;
	for(int32_t i = 1 ; i < 100 ; i++) {
		for(int32_t j = i + 1 ; ; j++) {
			int32_t digs = HowManyDigs( i , j );
			if( digs < 9 )	continue;
			if( digs > 9 )	break;
			if( IsDigital( i , j ) && !canAdd[i*j] ) {
				sum += i * j;
				canAdd[ i * j ] = 1;
			}
		}
	}
	printf("%d\n",sum);
}
int32_t main() {
	solve();
	return 0;
}
posted @ 2017-06-24 22:27  ojnQ  阅读(228)  评论(0编辑  收藏  举报