来源:牛客网
题目描述
7254是一个不寻常的数,因为它可以表示为7254 = 39 x 186,这个式子中1~9每个数字正好出现一次
输出所有这样的不同的式子(乘数交换被认为是相同的式子)
结果小的先输出;结果相同的,较小的乘数较小的先输出。
输入描述:
无
输出描述:
每一行输出一个式子,式子中的等号前后空格、乘号(用字母x代表)前后空格 较小的乘数写在前面
一开始想直接暴力枚举出来每一位的数,然后再判断符不符合条件。。。
实在是,太耗费时间了哈哈哈哈,笨蛋想法!
后来想了想,可以把1-9这九个数字存在数组里面,然后实现数组的全排列,对每一次排列得到的结果都去验证符不符合题意,这样不就可以了吗!
问题就在怎么实现全排列了。。
在数学上我们学过对一组n个元素进行不重复的排列,结果一共有 n!种,也就是从第一个位置开始,先放一个元素,此时有n种情况,第二个位子再放一个元素,此时有 n-1 种情况,以此类推。
搜了搜学到了一个新的函数,可以直接实现全排列。
next_permutation(a,a+n) 是个好东西!!
这个函数是实现对数组a的前n个元素进行全排列,但是进行全排列的数组一定要是有序的(升序),如果不是按照升序排列的,那系统只能找到该序列之后的全排列。
举个栗子
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[3]={1,2,3};
do{
cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
}while(next_permutation(a,a+3));
}
此时得到的结果是
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
如果我们数组并不是都按照升序排列的
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[3]={2,1,3};
do{
cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
}while(next_permutation(a,a+3));
}
此时得到的结果是
2 1 3
2 3 1
3 1 2
3 2 1
相比较第一次全都按照升序排列得到的全排列结果,可以清晰的看到本次全排列结果就是从数组初始顺序开始排序的。
获得全排列之后就好做了,因为题目中要求是每一个数字只能出现一次,那就是直接让每一次进行全排列之后得到的数组中每一位元素充当一位数字就好了。
两个乘数,要么就是一个两位数一个三位数,要么就是一个一位数一个四位数。
代码如下
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[9]={1,2,3,4,5,6,7,8,9};
do{
int num=a[0]*1000+a[1]*100+a[2]*10+a[3];
int x=a[4];
int y=a[5]*1000+a[6]*100+a[7]*10+a[8];
int x1=a[4]*10+a[5];
int y1=a[6]*100+a[7]*10+a[8];
if(num == x * y){
cout<<num<<" = "<<x<<" x "<<y<<endl;
}else if(num == x1 * y1){
cout<<num<<" = "<<x1<<" x "<<y1<<endl;
}
}while(next_permutation(a,a+9));
}