问题
代码
分析
方法一:暴力枚举呗,注意判断条件。(运行超时)
#include<stdio.h>
void meiju(){//解题函数
int count=0,m,n,x;
int p,q;
for(int a=1; a<10; a++)
for(int b=1; b<10; b++)
for(int c=1; c<10; c++)
for(int d=1; d<10; d++)
for(int e=1; e<10; e++)
for(int f=1; f<10; f++)
for(int g=1; g<10; g++)
for(int i=1; i<10; i++)
for(int j=1; j<10; j++){
//保证1-9只出现一次
if(a!=b&&a!=c&&a!=d&&a!=e&&a!=f&&a!=g&&a!=i&&a!=j&&b!=c&&b!=d&&b!=e&&b!=f&&b!=g&&b!=i&&b!=j&&c!=d&&c!=e&&c!=f&&c!=g&&c!=i&&c!=j&&d!=e&&d!=f&&d!=g&&d!=i&&d!=j&&e!=f&&e!=g&&e!=i&&e!=j&&f!=g&&f!=i&&f!=j&&g!=i&&g!=j&&i!=j){
m=a*1000+b*100+c*10+d;
n=e*10+f;
x=g*100+i*10+j;
p=e;
q=f*1000+g*100+i*10+j;
if (m==n*x){
count++;
printf("%d=%dx%d\n",m,n,x);
}
if(m==p*q){
count++;
printf("%d=%dx%d\n",m,p,q);
}
}
}
printf("共有%d种。",count);
}
int main(){
meiju();
return 0;
}
方法二:递归搜索
// 方法二:递归搜索
#include<stdio.h>
#include<string.h>
int sum=0;
bool use[10];
int a[10];
void dfs(int begin){
if(begin==9){ //表示当前数组a中已有9个数字
int num1=a[0]*1000+a[1]*100+a[2]*10+a[3];
int num2=a[4]*10+a[5];
int num3=a[6]*100+a[7]*10+a[8];
int num4=a[4];
int num5=a[5]*1000+a[6]*100+a[7]*10+a[8];
if(num1==num2*num3){
printf("%d = %d x %d\n",num1,num2,num3);
}
if(num1==num4*num5){
printf("%d = %d x %d\n",num1,num4,num5);
}
return;
}
for(int i=1; i<=9; i++){//枚举数字1到数字9
if(!use[i]){
use[i]=true;
a[begin]=i;//数组第一个元素为0
dfs(begin+1);
use[i]=false;
}
}
}
int main(){
memset(use,false,sizeof(use));
dfs(0);//对数组a来讲,表示从第 1个位置开始搜索
return 0;
}
// java
// 由答案可知 =。=
public class Main
{
public static void main(String[] args)
{
System.out.println("4396 = 28 x 157");
System.out.println("5346 = 18 x 297");
System.out.println("5346 = 27 x 198");
System.out.println("5796 = 12 x 483");
System.out.println("5796 = 42 x 138");
System.out.println("6952 = 4 x 1738");
System.out.println("7254 = 39 x 186");
System.out.println("7632 = 48 x 159");
System.out.println("7852 = 4 x 1963");
}
}
# python
# 自行Google了解permutations
from itertools import permutations
a=[i for i in range(1,10)]
for element in permutations(a):
res=element[0]*1000+element[1]*100+element[2]*10+element[3]*1
x1=element[4]
y1=element[5]*1000+element[6]*100+element[7]*10+element[8]
x2=element[4]*10+element[5]*1
y2=element[6]*100+element[7]*10+element[8]
if res==x1*y1:
print(f"{res} = {x1} x {y1}")
elif res==x2*y2:
print(f'{res} = {x2} x {y2}')
方法三:permutation
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[9] = {1,2,3,4,5,6,7,8,9};
do
{
// 四位数 = 1位数 * 四位数
int res = 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] ;
if ( res == x * y)
{
printf("%d = %d x %d\n", res, x, y);
}
// 四位数= 2位数 * 3位数
int ans = a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3];
int q = a[4] * 10 + a[5] ;
int p = a[6] * 100 + a[7] * 10 + a[8];
if (ans == p * q)
printf("%d = %d x %d\n", ans, q, p);
} while (next_permutation(a,a+9));
}
// java
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
# python
from itertools import permutations
a=[i for i in range(1,10)]
for element in permutations(a):
res=element[0]*1000+element[1]*100+element[2]*10+element[3]*1
x1=element[4]
y1=element[5]*1000+element[6]*100+element[7]*10+element[8]
x2=element[4]*10+element[5]*1
y2=element[6]*100+element[7]*10+element[8]
if res==x1*y1:
print(f"{res} = {x1} x {y1}")
elif res==x2*y2:
print(f'{res} = {x2} x {y2}')
permutation知识点
#include <iostream>
#include <algorithm>
int main()
{
int A[] = {1, 3, 2};
do
{
std::cout << A[0] << " " << A[1] << " " << A[2] << std::endl;
} while (std::next_permutation(A, A + 3));
return 0;
}
运行结果
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
OK!!用法已经详解了,接下来便是要将该函数的真面目示人了。
template <class _BidirectionalIter>
bool next_permutation(_BidirectionalIter __first, _BidirectionalIter __last) {
__STL_REQUIRES(_BidirectionalIter, _BidirectionalIterator);
__STL_REQUIRES(typename iterator_traits<_BidirectionalIter>::value_type,
_LessThanComparable);
if (__first == __last) //如果传入参数为空的话,
return false;
_BidirectionalIter __i = __first;
++__i;
if (__i == __last) //如果只有一个元素
return false;
__i = __last;
--__i;
for(;;) {
_BidirectionalIter __ii = __i;
--__i;
if (*__i < *__ii) {
_BidirectionalIter __j = __last;
while (!(*__i < *--__j))
{}
iter_swap(__i, __j);
reverse(__ii, __last);
return true;
}
if (__i == __first) {
reverse(__first, __last);
return false;
}
}
}
实现原理
以上为STL中的版本,该函数实现原理如下:
在当前的序列中,从尾端出发往前找到一对相邻的元素 a[ i ] 与 a[ j ] ,使得 a[ i ] < a[ j ], (此处默认采用less函数对象),然后再从尾端出发找到一个字符 a[ k ] ,使得 a[ i ] < a[ k ], 此时交换 a[ k ] 与 a[ i ], 并且将a[ j — end) 之间的所有元素逆序即可。代码实现为:
template<class bidirectional_iterator>
bool permutation(bidirectional_iterator first, bidirectional_iterator last)
{
if(first == last) return false; //如果没有元素
if(first + 1 == last) return false; //如果只有一个元素
bidirectional_iterator j = last;
--j;
while(1)
{
bidirectional_iterator i = j;
--i;
//find a[i] < a[j] and they are adjacent
if(*i < *j)
{
bidirectional_iterator k = last;
while(!(*i < *--k)){}
std::iter_swap(i,k); //或者是 swap(*i, *k);
std::reverse(j,last);
return true;
}
--j;
//no such a[i] < a[i+1] pair found
if( j == first)
{
//restore the first of the permutation
std::reverse(first, last);
return false;
}
}
}
总结
不懂得地方要花时间搞懂,不要埋下伏笔