题目描述
万圣节有一个Party,XadillaX显然也要去凑热闹了。因为去凑热闹的人数非常庞大,几十W的数量级吧,自然要进场就需要有门票了。很幸运的,XadillaX竟然拿到了一张真·门票!这真·门票的排列规则有些奇怪:
门票号是由0~6组成的六位数(0~6这几个数字可重用)
每一个门票号的每一位不能有三个连续相同的数字(如123335是不行的)
每一个门票号相邻的两位相差必须在四以下(≤4)(如016245是不行的)
要求至少有两个子函数。
子函数1,参数为n,判断数字n是否有三个连续相同的数字。
子函数2,参数为n,判断数字n相邻的两位差是否在4以下。
输入
第一行一个n,代表输入个数
接下去n行,每行两个数字x,y(x <= y)
输出
对于每个测试,输出x到y之间的门票编号。每个测试结尾之间空行。
输入输出样例
输入样例1 <-复制
2
001001 001002
001011 001012
输出样例1
001001
001002
001011
001012
AC代码
#include<stdio.h>
int weishu(int j, int n); // 判断数字 n 的第 j 位数字
int must1(int n); // 判断数字 n 是否有三个连续相同的数字
int must2(int n); // 判断数字 n 相邻的两位差是否在 4 以下
int main()
{
int n, x, y, t, i, j;
scanf("%d", &t); // 输入测试用例的数量
while (t--)
{
scanf("%d%d", &x, &y); // 输入起始和结束数字
for (i = x; i <= y; i++)
{
for (j = 0; j < 6; j++)
{
if (weishu(j, i) > 6)
break; // 判断数字位数是否超过 6 位
}
if (j == 6)
{
if (must1(i) && must2(i)) // 满足条件1和条件2
printf("%06d\n", i); // 输出门票编号
}
}
printf("\n"); // 输出空行
}
}
// 判断数字 n 的第 j 位数字
int weishu(int j, int n)
{
int i, jie = 1;
for (i = 0; i < j; i++)
jie *= 10;
n /= jie;
n %= 10;
return n;
}
// 判断数字 n 是否有三个连续相同的数字
int must1(int n)
{
int i;
for (i = 0; i < 4; i++)
{
if (weishu(i, n) == weishu(i + 1, n) && weishu(i + 2, n) == weishu(i + 1, n))
return 0; // 存在三个连续相同的数字,不满足条件
}
return 1; // 不满足条件1,满足条件
}
// 判断数字 n 相邻的两位差是否在 4 以下
int must2(int n)
{
int i;
for (i = 0; i < 5; i++)
{
if (weishu(i, n) - weishu(i + 1, n) > 4 || weishu(i, n) - weishu(i + 1, n) < -4)
return 0; // 相邻的两位差超过 4,不满足条件
}
return 1; // 不满足条件2,满足条件
}
根据输入的两个数字 x 和 y,判断在 x 和 y 之间的六位门票编号是否满足一定的条件,并输出满足条件的门票编号。
主要的逻辑是通过两个子函数 must1()
和 must2()
来判断门票编号是否满足条件1和条件2。其中,weishu()
函数用于获取数字的每一位,判断是否满足条件。
具体的步骤如下:
- 首先,读取输入的测试用例的数量
t
。 - 对于每个测试用例,读取起始数字
x
和结束数字y
。 - 使用两个嵌套循环,从
x
遍历到y
,判断每个数字是否满足条件。 - 在内部循环中,通过调用
weishu()
函数判断数字的位数是否超过 6 位,如果超过则跳出内部循环。 - 如果数字的位数不超过 6 位,则继续判断数字是否满足条件1和条件2。如果满足条件,则输出门票编号。
- 输出完所有满足条件的门票编号后,输出一个空行。
- 重复上述步骤,直到处理完所有的测试用例。
(by 归忆)