题意:找出所有形如 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;
}