神奇算式
由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。
比如:
210 x 6 = 1260
8 x 473 = 3784
27 x 81 = 2187
都符合要求。如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。
请填写该数字,通过浏览器提交答案,不要填写多余内容(例如:列出所有算式)。
答案:12
题目解析
这个题目在前面也遇到了类似的,解法可以是暴力枚举,方法也是相似的,枚举所有满足的式子。需要注意的是,这里面的情形可以是三位数*两位数,也可以是两位数乘以两位数,那么如果直接枚举的话,肯定会出现重复的式子。所以需要判断!!!
对两位数*两位数的式子进行判断,保证两个两位数不能重复,方法就是要么前面数小于后面数,要么后面数小于前面数,两种取一种就可以了。
#include <iostream>
#include <unordered_set>
#include <string.h>
#include <sstream>
#include <algorithm>
using namespace std;
int ans=0;
bool check(int res, int x){
stringstream ss;
string str_res, str_x;
ss << res;
ss >> str_res;
stringstream ss1; //重新申请ss,注意 !
ss1 << x;
ss1 >> str_x;
sort(str_res.begin(), str_res.end());
sort(str_x.begin(), str_x.end());
if (str_res == str_x){
return true;
} else{
return false;
}
}
int main(int argc, char** argv) {
for(int i = 1; i < 10; i++){
for(int j = 0; j < 10; j++){
if(i != j){
for(int k = 0; k < 10; k++){
if(k != i && k != j){
for(int l = 0; l < 10; l++){
if(l != i && l != j && l != k){
int res = i*1000 + j*100 + k*10 + l;
int r1 = i*(j*100 + k*10 + l); //三位数*一位数
if(check(res, r1)){
ans ++;
}
int r2 = (i*10+j) * (k*10+l); //两位数*两位数
if( (i*10+j) < (k*10+l) && check(res, r2)){
//注意对两个两位数的大小进行判断,(i*10+j) < (k*10+l),不然会重复
ans++;
}
}
}
}
}
}
}
}
cout << ans << endl;
return 0;
}