c语言题目排列式
来源:牛客网
题目描述
7254是一个不寻常的数,因为它可以表示为7254 = 39 x 186,这个式子中1~9每个数字正好出现一次
输出所有这样的不同的式子(乘数交换被认为是相同的式子)
结果小的先输出;结果相同的,较小的乘数较小的先输出。
输入描述:
每一行输出一个式子,式子中的等号前后空格、乘号(用字母x代表)前后空格
较小的乘数写在前面
输出描述:
下面是我对于此题的理解
从此题的实例输出上来看,数的分布都是在1000-9999之间的,但由于题目的要求,范围可以继续缩小至1234-9876之间。那我们可以从1234开始,看它会被哪两个数整除。从1开始,1234/1=1234,这时候我们得到了3个数字,分别是1234,1,1234这三个数。我们再创建一个数组sum[10],将里面的数都设为0,对这三个数进行一个拆分,1234拆成1 2 3 4,1拆成1,1234拆成1 2 3 4,分别对应着1 2 3 4这几个数字,那对应的数组里面的内容就要对应的相加,最后再统计1 2 3 4 5 6 7 8 9是否都出现过一次即可。
不过要注意一个点,就是一个式子它可能有两种表示方式,例如7254 = 39 x 186还可以用7254 = 186 x 39来表示,因此对于除数的范围也要有限制,限制到其根号位即可,sqrt(7254)就是除数的最大值了
这是我的代码
#include<stdio.h>
#include<math.h>
int panduan(int i, int j, int k)
{
int sum[10] = { 0 };
int a = 1, n;
while (i > 0)//对数的拆分
{
n = i % 10;
sum[n]++;//对应数组数字
i /= 10;
if (sum[n] == 2)//1-9其中如果有一个数字达到2个了就不符合题目需求了
return 0;
}
while (j > 0)//同上
{
n = j % 10;
sum[n]++;
j /= 10;
if (sum[n] == 2)
return 0;
}
while (k > 0)
{
n = k % 10;
sum[n]++;
k /= 10;
if (sum[n] == 2)
return 0;
}
for (n = 1; n < 10; n++)//最后再判断一次1-9是否都只出现过一次
{
if (sum[n] != 1)
return 0;
}
return a;
}
int main()
{
int i, j, k;
for (i = 1234; i <= 9876; i++)//对数的查找,遍历手段
{
for (j = 1; j <= sqrt(i); j++)//对于除数的限制
{
k = i / j;
if (k * j == i)
{
if (panduan(i, j, k))//判断i,j,k三个数的数字是否刚好1-9各一个
{
printf("%d = %d x %d\n", i, j, k);//输出
}
}
return 0;
}