刚翻到<<算法竞赛入门经典(第2版)>>,看到上面有一道这个题,感觉不错,记录以下;
题目为:
输入正整数n,按从小到大的顺序输出所有形如abcde/fghij = n的表达式,其中a~j恰好 为数字0~9的一个排列(可以有前导0),2≤n≤79。
样例输入:
62
样例输出:
79546 / 01283 = 62
94736 / 01528 = 62
分析:本题有两种解法,1:使用排列组合,然后判断x*y是否和n相等即可,然而其运算速度会相当的慢,因为要计算10!,虽然判断比较简单,但是不好
2:第二种就是枚举了,因为n>2,所以被除数一定是大于除数的,所以被除数可以从12345开始,到98765结束,
其过程是已知x和n,只需判断x%n是否等于0,如果等于0,则y符合条件,记录下y的每一位数字,(用来判断数字是否相同),然后还需要记录下x的每一位数子,其实可以用一个数组即可.然后就是去除含有相同数子的组合,最后输出符合条件的组合即可.
代码如下
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,x,y,m;//
int i,j,flag;//flag相当于一个bool变量,用于判断数子是否有相同的
int a[10];
while(1)//我设置的无限循环,如有其它需要请改变量即可
{
scanf("%d",&n);
for(x=12345;x<=98765;x++)
{
memset(a,0,sizeof(a));
flag = 1;
m = x;
if(x%n== 0) //记录y的各个位
{
y = x/n;
for(i=4;i>=0;i--)
{
a[i] = y%10;
y = y/10;
}
}
for(i=9;i>=5;i--) //记录x的各个位
{
a[i] = m%10;
m = m/10;
}
for(i=0;i<9;i++) //判断有没有重复的
{
for(j=i+1;j<=9;j++)
{
if(a[i] == a[j])
{
flag = 0;
break;
}
}
if(flag ==0)
break;
}
if(flag==1)
{
for(i=5;i<=9;i++)
printf("%d",a[i]);
printf("/");
for(i=0;i<5;i++)
printf("%d",a[i]);
printf("=%d\n",n);
}
}
}
return 0;
}