题解 | #Repeater#
Repeater
https://www.nowcoder.com/practice/97fd3a67eff4455ea3f4d179d6467de9
跨考生,由于之前学习数据结构的内容中关于字符串的算法应用不多,故在做复杂的字符串相关问题时遇到诸多困难,只能由读高赞答案增加理解,在此记录自己学到的一些内容
基础知识
原本只会用 scanf 读取输入,增加了解了 getchar 和
- scanf() 可输入不包含空格的字符串,不读取换行符,空格和回车表示输入完毕,通常用于读入单个输入字符
- gets ()
char *gets(char *str)
用于读入一行数据并存储在str
中,当读取到换行符时,或者到达文件末尾时停止 - getchar() 只能读取用户输入缓存区的一个字符,包括换行符
- pow ()
*double pow(double x, double y)
返回 x 的 y 次幂,即属于标准库 <math.h>
- puts ()
int puts(const char *str)
输出一个字符串,直到空字符,但不包括空字符。换行符会被追加到输出中
- 在 二维字符数组
char c[][]
的行中存入的字符串,可用c[][]
逐个读出,也可用c[]
直接按行读出 如c[0]=apple
则c[0][0]==a
,c[0][4]==e
解题思路
- 先用辅助数组来构建图形,再将数组依次输出
- 若要直接输出字符串组成图形,只能按行构建,而数组则可以比较自由得构建
题解
#include <stdio.h> #include <math.h> int N, Q; // N 为模板边长,Q 为边长放大倍率 // 存储模板 char t[6][6]; // 存储输出图形,行多 1 用于存储结束符号 char output[3000][3001]; // 递归: 找到完成图中每一个原模板的左上起点 // level 初始等于 Q, 之后每层递归减少 1 // x,y 是起始点坐标 void draw(int level, int x, int y) { // 子图大小 = 原式边长^次一层级的边长放大倍率 int eSize = (int)pow(N, level - 1); int i, j; // 开始输入 // 当 level 为 1 时,代表找到等于初始模板大小的层级,故以起始坐标为左上角,输入一个初始模板 if (level == 1) { for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { output[x + i][y + j] = t[i][j]; } } } // 据初始模板定位子图的起始位置 else { for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { if (t[i][j] != ' ') { // 由于 i,j 都由 0 开始遍历,故 eSize*i/eSize*j 可以找到当前图的起始位置,即 (x,y) draw(level - 1, x + eSize * i, y + eSize * j); } } } } } int main() { while (scanf("%d", &N) != EOF) { if (N == 0 || N > 5) { break; } getchar(); //去掉多余的换行符,否会被 getchar() 抓取 int i, j; for (i = 0; i < N; i++) //输入模板 { gets(t[i]); } scanf("%d", &Q); int size = (int)pow(N, Q); //计算最终大小 // 初始化输出数组 for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { output[i][j] = ' '; } output[i][size] = '\0'; } // 进入递归 draw(Q, 0, 0); // 输出图形 for (i = 0; i < size; i++) { puts(output[i]); } } return 0; }