目录
描述
小乐乐从老师口中听到了二段数这个名词,想更深入的了解二段数。
二段数是这样的正整数:恰好包含两种不同的十进制数字s和t,s不是0,并且s的所有出现均排列在所有的t的前面。例如,44444411是二段数(s是4,t是1),41、10000000和5555556也是。但4444114和44444都不是二段数。
这时老师问小乐乐:给你一个任意的正整数n,你能求出比n大并且是n的倍数的最小二段数吗?请你帮助小乐乐解答这个问题。
输入描述:
多组输入,每组输入包含一个正整数n (1 ≤ n ≤ 99999)
题目保证测试数据总数不超过500组,当输入n=0时程序结束。
输出描述:
对于每组测试用例,输出正整数n,后面紧跟“: ”,输出答案并换行,即比n大且是n的倍数的最小二段数。
示例1
输入:
1 2019 0输出:
1: 10 2019: 9999999993
代码实现:
#include <stdio.h>
#include<math.h>
int a[9999], b[999];
int apm, aps, apn, apt, aptotal;
int m, s, n, t, total;
int ck()
{
if (total > 5)
return 1;
int a = s;
int b = t;
for (int i = 0; i < m; i++)
{
a = a * 10 + s;
}
for (int i = 0; i < total - m; i++)
{
a *= 10;
}
for (int i = 1; i < total - m; i++)
{
b = t + b * 10;
}
return a + b > n;
}
int main()
{
while (scanf("%d", &n) && n)
{
printf("%d: ", n);
if (n == 1)
{
printf("10\n");
continue;
}
a[0] = 1;
b[0] = 1;
for (int i = 1; i < 9999; i++)
{
a[i] = (a[i - 1] * 10 + 1) % n;
}
for (int i = 1; i < 999; i++)
{
b[i] = b[i - 1] * 10 % n;
}
for (total = 1, aps = 0; total < 9999; total++)
{
int k = 0;
if ((n % 10 == 0 || n % 25 == 0) && total > 11)
k = total - 11;
//m个s,total-m个t
for (m = k; m < total; m++)
for (s = 1; s < 10; s++)
for (t = 0; t < ((n % 10 == 0) ? 1 : 10); t++)
if ((t != s) &&
(((long long)a[m]) * b[total - m] * s + t * a[total - m - 1]) % n == 0 && ck() &&
(!aps || aps > s))
{
aps = s;
apt = t;
aptotal = total;
apm = m;
}
if (aps)
break;
}
for (int i = 0; i < apm + 1; i++)
{
printf("%d", aps);
}
for (int i = 0; i < aptotal - apm; i++)
{
printf("%d", apt);
}
printf("\n");
}
return 0;
}