算法提高 排列式
时间限制:1.0s 内存限制:256.0MB
问题描述
7254是一个不寻常的数,因为它可以表示为7254 = 39 x 186,这个式子中1~9每个数字正好出现一次
输出所有这样的不同的式子(乘数交换被认为是相同的式子)
结果小的先输出;结果相同的,较小的乘数较小的先输出。
输出格式
每一行输出一个式子,式子中的等号前后空格、乘号(用字母x代表)前后空格
较小的乘数写在前面
样例输出
问题中的式子在结果中会出现一行如下:
7254 = 39 x 186
分析:对于待求的等式:
积 = 被乘数 x 乘数
若积为三位数,则被乘数和乘数的位数之和为6,但是不论是 一位 x 五位、二位 x 四位、三位 x 三位 都不可能得到一个三位数的积,排除积为三位数的可能。
若积为五位数,则被乘数和乘数的位数之和为4,但是不论是 一位 x 三位、二位 x 二位 都不可能得到一个五位数的积,排除积为五位数的可能。
所以积只可能为四位数,被乘数和乘数要么是 一位 x 四位,要么是 二位 x 三位。
#include <stdio.h>
#include <memory.h>
int main()
{
int dump, is_valid;
int copied_appeared[10] = { 0 };
for (int i = 1234; i <= 9876; ++i)
{
int appeared[10] = { 0 };
dump = i;
while (dump)
{
appeared[dump % 10]++;
dump /= 10;
}
is_valid = 1;
for (int k = 1; k <= 9; ++k)
{
if (appeared[k] > 1)
{
is_valid = 0;
break;
}
}
if (is_valid)
{
int multiplier1, multiplier2;
for (multiplier1 = 2; multiplier1 * multiplier1 < i; ++multiplier1)
{
if (i % multiplier1 != 0)
continue;
is_valid = 1;
memcpy(copied_appeared, appeared, 10 * sizeof(int));
dump = multiplier1;
while (dump)
{
appeared[dump % 10]++;
dump /= 10;
}
dump = multiplier2 = i / multiplier1;
while (dump)
{
appeared[dump % 10]++;
dump /= 10;
}
for (int k = 1; k <= 9; ++k)
{
if (appeared[k] != 1)
{
is_valid = 0;
break;
}
}
if (is_valid)
printf("%d = %d x %d\n", i, multiplier1, multiplier2);
memcpy(appeared, copied_appeared, 10 * sizeof(int));
}
}
}
return 0;
}