/* 标题:神奇算式 由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