/*
标题:神奇算式
由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。
比如:
210 x 6 = 1260
8 x 473 = 3784
27 x 81 = 2187
都符合要求。
如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。
请填写该数字,通过浏览器提交答案,不要填写多余内容(例如:列出所有算式)。
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
using namespace std;
/*
如果是初始化,只要定义第一个元素为0,后面就全为0了,如
int a[10] = {0};
如果是在定义以后想全部赋为0,用memset()函数是比较快的。
如:
int a[10];
memset(a, 0, sizeof(int)*10);
*/
int flag[10];
//compares the two arrays so as to know if they have the same elements
bool f(int a1[],int a2[])
{
for(int i=0;i<10;i++)
{
if(a1[i]!=a2[i]) return false;
}
return true;
}
int main()
{
for(int i=1000;i<=9999;i++)
{
memset(flag, 0, sizeof(int)*10);
int n=i;
int a[4] = {0};
{
a[0]=n/1000;n=n%1000;
a[1]=n/100;n=n%100;
a[2]=n/10;n=n%10;
a[3]=n;//求每一位的数字
}
n=i;
while(n)//求解i每一位的组成
{
flag[n%10]++;
n/=10;
//cout<<flag[0]<<flag[1]<<flag[2]<<flag[3]<<flag[4]<<flag[5]<<flag[6]<<flag[7]<<flag[8]<<flag[9]<<flag[10]<<endl;
}
int final[3];//存放每一种组合的相乘的结果
{
final[0]=(a[0])*(a[1]*100+a[2]*10+a[3]);
final[1]=(a[0]*10+a[1])*(+a[2]*10+a[3]);
final[2]=(a[0]*100+a[1]*10+a[2])*(a[3]);
}
int flag1[3][10]={0};//存放每个结果的每一位的组成
for(int j=0;j<3;j++)
{
n=final[j];
while(n)
{
flag1[j][n%10]++;
n/=10;
}
//cout<<flag1[j][0]<<flag1[j][1]<<flag1[j][2]<<flag1[j][3]<<flag1[j][4]<<flag1[j][5]<<flag1[j][6]<<flag1[j][7]<<flag1[j][8]<<flag1[j][9]<<flag1[j][10]<<endl;
}
bool b;
//case1
if(f(flag,flag1[0])) cout<<a[0]<<"*"<<a[1]*100+a[2]*10+a[3]<<"="<<final[0]<<endl;
//case2
if(f(flag,flag1[1])) cout<<a[0]*10+a[1]<<"*"<<a[2]*10+a[3]<<"="<<final[1]<<endl;
//case3
if(f(flag,flag1[2])) cout<<a[0]*100+a[1]*10+a[2]<<"*"<<a[3]<<"="<<final[2]<<endl;
}
return 0;
}
思想并不复杂,就是从1000到9999,把每个数拆分成四位存到一个数组里,然后考虑每个数,对每一种分解情况考虑两个因子的组成是不是和原数一样,是就输出。
主要是要注意构造好存放每一位的标志数组flag和flag1,因为这两个数组没构造好,导致我浪费了一个小时调试,TNND。
tz@COI HZAU
2018/3/14