文章目录
一、杨辉三角
给出 n(n≤20),输出杨辉三角的前 n 行。
如果你不知道什么是杨辉三角,可以观察样例找找规律。
1.样例
> 输入:
6
> 输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
2.做题思路
又是似曾相识的感觉,和之前的《直角三角形》长得好像,但是这次输出的三角形,每个数的值是和上一行的2个数有关系的,所以很显然就是要考二维数组,然后再使用2个for循环把他按照格式输出。3.代码如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
static int a[20][20];
int n;
scanf_s("%d", &n);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i + 1; j++)
{
if (i == 0 || j == 0 || i == j) a[i][j] = 1; /* 使每行两侧的数等于1 */
else a[i][j] = a[i - 1][j - 1] + a[i - 1][j]; /* 非两侧的数的值为上一列前后2两数之和 */
printf("%d ", a[i][j]); /* 输出该数 */
}
printf("\n"); /* 每行结束需要换行 */
}
return 0;
}
二、珠心算测验
某学校的珠心算老师采用一种快速考察珠心算加法能力的测验方法。他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?
最近老师出了一些测验题,请你帮忙求出答案。
输入格式:
第一行包含一个整数nn,表示测试题中给出的正整数个数。
第二行有nn个正整数,每两个正整数之间用一个空格隔开,表示测试题中给出的正整数。
输出格式
一个整数,表示测验题答案。
(本题目为2014NOIP普及T1)
1.样例
> 输入:
4
1 2 3 4
> 输出:
2
样例说明
由1+2=3,1+3=41+2=3,1+3=4,故满足测试要求的答案为2。
注意,加数和被加数必须是集合中的两个不同的数。
2.做题思路
这道题是不是和上次那个《两数之和》特别特别像呢? 不同点就在于这道题的目标值不是你输入的,而每个数都可以作为目标值,这道题中“其中有多少个数,恰好等于集合中另外两个(不同的)数之和”这句话特别关键,我第一次就错在了这,不同的2个数对相加都等于目标值的话,只能算1个答案(在{1,2,3,4,5}中,1+4=5,2+3=5,结果只算1个)所以为了提升速度,在找到第一个结果后立马重新选择目标值,过程中进行计数即可。3.代码如下:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, sum = 0;
int a[100];
scanf_s("%d", &n);
for (int i = 0; i < n; i++) /* 录入数据 */
scanf_s("%d", &a[i]);
for (int i = 0; i < n; i++) /* 目标值循环 */
{
for (int j = 0; j < n - 1; j++) /* 被加数循环 */
{
for (int z = j + 1; z < n; z++) /* 加数循环 */
{
if (a[j] + a[z] == a[i]) /* 判断加数与被加数是否为目标值 */
{
sum++; /* 条件成立后,答案+1 */
goto end; /* 找到结果后立马退出2个for循环,重新选择目标值 */
}
}
}
end:;
}
printf("%d", sum);
return 0;
}
三、压缩技术
设某汉字由N × N的0和1的点阵图案组成。
我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个0,第二个数表示接下来连续有几个1,第三个数再接下来连续有几个0,第四个数接着连续几个1,以此类推……
例如: 以下汉字点阵图案:
0001000
0001000
0001111
0001000
0001000
0001000
1111111
对应的压缩码是: 7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是N ,其余各位表示交替表示0和1 的个数,压缩码保证 N × N=交替的各位数之和)
输入格式:
一行,压缩码。
输出格式:
汉字点阵图(点阵符号之间不留空格)。(3<=N<=200)
1.样例
> 输入:
7 3 1 6 1 6 4 3 1 6 1 6 1 3 7
> 输出:
0001000
0001000
0001111
0001000
0001000
0001000
1111111
2.做题思路
一开始容易想到为二维数组的应用,但是发现自己无法实现,所以就想到了将一维数组按照需要格式输出,按照所给的压缩码,将一维数组按照顺序初始化,然后按照格式输出就可以了。详细请看代码。3.代码如下:
#include <stdio.h>
#include <stdlib.h>
#define LEN 40000 /* 宏定义长度 */
int main()
{
static int a[LEN], b[LEN];
int n, sum = 0;
int i, j;
i = j = 0;
scanf_s("%d", &n); /* 第一个数N */
while (sum != n * n) /* 录入数之和等于矩阵N*N时录入结束 */
{
scanf_s("%d", &b[i]);
sum += b[i];
i++;
}
int lenth = i; /* lenth为录入数的数量 */
int x = 0;
for (i = 0; i < lenth; i++) /* 0和1的交错赋值次数 */
{
for (j = 0; j < b[i]; j++) /* 0和1交错赋值 */
{
if (i % 2 == 0) a[x] = 0;
else a[x] = 1;
x++; /* 记录次数实现交错 */
}
}
x = 0;
for (i = 0; i < n; i++) /* 共n行 */
{
for (j = 0; j < n; j++) /* 每n个为一行 */
{
printf("%d", a[x]);
x++;
}
printf("\n");
}
return 0;
}
四、显示器
液晶屏上,每个阿拉伯数字都是可以显示成 3×5 的点阵的(其中 X 表示亮点,. 表示暗点)。现在给出数字位数(不超过 100)和一串数字,要求输出这些数字在显示屏上的效果。数字的显示方式如同样例输出,注意每个数字之间都有一列间隔。
1.样例
>输入:
10
0123456789
>输出:
XXX...X.XXX.XXX.X.X.XXX.XXX.XXX.XXX.XXX
X.X...X...X...X.X.X.X...X.....X.X.X.X.X
X.X...X.XXX.XXX.XXX.XXX.XXX...X.XXX.XXX
X.X...X.X.....X...X...X.X.X...X.X.X...X
XXX...X.XXX.XXX...X.XXX.XXX...X.XXX.XXX
2.做题思路
肯定会想到二维数组吧,的确,就是二维数组,个人觉得这道题主要考了我字符串的应用😂,写完发现这道题没什么难度,难的就是不敢那么想。个人做法有些神奇。3.代码如下:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
static char a[101];
static char ch[5][1000];
int n;
scanf_s("%d", &n);
scanf_s("%s", a, n + 1); /* 录入需要在显示器上显示的数字 */
for (int i = 0; i < n ; i++)
{
int j = 4 * (i + 1) - 3; /* 设置每个字符串的起始地址,使得字符串不重叠 */
if (a[i] == '0')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "X.X.");
strcpy_s(&ch[2][j], 5, "X.X.");
strcpy_s(&ch[3][j], 5, "X.X.");
strcpy_s(&ch[4][j], 5, "XXX.");
}
else if (a[i] == '1')
{
strcpy_s(&ch[0][j], 5, "..X.");
strcpy_s(&ch[1][j], 5, "..X.");
strcpy_s(&ch[2][j], 5, "..X.");
strcpy_s(&ch[3][j], 5, "..X.");
strcpy_s(&ch[4][j], 5, "..X.");
}
else if (a[i] == '2')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "..X.");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "X...");
strcpy_s(&ch[4][j], 5, "XXX.");
}
else if (a[i] == '3')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "..X.");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "..X.");
strcpy_s(&ch[4][j], 5, "XXX.");
}
else if (a[i] == '4')
{
strcpy_s(&ch[0][j], 5, "X.X.");
strcpy_s(&ch[1][j], 5, "X.X.");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "..X.");
strcpy_s(&ch[4][j], 5, "..X.");
}
else if (a[i] == '5')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "X...");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "..X.");
strcpy_s(&ch[4][j], 5, "XXX.");
}
else if (a[i] == '6')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "X...");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "X.X.");
strcpy_s(&ch[4][j], 5, "XXX.");
}
else if (a[i] == '7')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "..X.");
strcpy_s(&ch[2][j], 5, "..X.");
strcpy_s(&ch[3][j], 5, "..X.");
strcpy_s(&ch[4][j], 5, "..X.");
}
else if (a[i] == '8')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "X.X.");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "X.X.");
strcpy_s(&ch[4][j], 5, "XXX.");
}
else if (a[i] == '9')
{
strcpy_s(&ch[0][j], 5, "XXX.");
strcpy_s(&ch[1][j], 5, "X.X.");
strcpy_s(&ch[2][j], 5, "XXX.");
strcpy_s(&ch[3][j], 5, "..X.");
strcpy_s(&ch[4][j], 5, "XXX.");
}
}
for (int i = 0; i < 5; i++) /* 共有5行 */
{
ch[i][strlen(&ch[i][1])] = '\0'; /* 最后一行的时候要把多余的.删掉 */
printf("%s\n", &ch[i][1]); /* 输出本行字符串 */
}
return 0;
}
在查看其他题解的过程中,我惊奇的发现了一个代码很短的一个答案,各位也可以学习一下。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
const char l[50][50] =
{
{"XXX\0..X\0XXX\0XXX\0X.X\0XXX\0XXX\0XXX\0XXX\0XXX\0"}, \
{"X.X\0..X\0..X\0..X\0X.X\0X..\0X..\0..X\0X.X\0X.X\0"}, \
{"X.X\0..X\0XXX\0XXX\0XXX\0XXX\0XXX\0..X\0XXX\0XXX\0"}, \
{"X.X\0..X\0X..\0..X\0..X\0..X\0X.X\0..X\0X.X\0..X\0"}, \
{"XXX\0..X\0XXX\0XXX\0..X\0XXX\0XXX\0..X\0XXX\0XXX\0"}
};
int main()
{
int i, j, n;
char x[100];
scanf_s("%d\n", &n);
for (i = 0; i < n; i++) scanf_s("%c", x + i, 1);
for (i = 0; i < 5; i++)
{
for (j = 0; j < n; j++)
{
printf("%s", l[i] + (x[j] - 48) * 4);
if (j < n - 1) putchar('.');
}
putchar('\n');
}
return 0;
}
总结
上面的题都考察了数组和循环语句的使用,这些题型就是为了锻炼让代码跟着思维走,上面的代码都是自己根据思维写的,在洛谷上也全部通过了,速度和代码长度也相对好一些,欢迎点评😀
- 在洛谷测试需要修改strcpy_s,scanf_s函数,上述代码在VS2019中可正常运行,如果不修改上述函数,可能会编译错误。字符串修改可查看VS2019中部分字符串函数的使用