题目介绍
Harmony is indispensible in our daily life and no one can live without it----may be Facer is the only exception. One day it is rumored that repeat painting will create harmony and then hundreds of people started their endless drawing. Their paintings were based on a small template and a simple method of duplicating. Though Facer can easily imagine the style of the whole picture, but he cannot find the essential harmony. Now you need to help Facer by showing the picture on computer. You will be given a template containing only one kind of character and spaces, and the template shows how the endless picture is created----use the characters as basic elements and put them in the right position to form a bigger template, and then repeat and repeat doing that. Here is an example.
样例输入与输出
题目分析
这是一道模拟题,也是需要我们根据输入输出样例去找规律,但是并不像简单的模拟图形输出,该题还需要用到递归的思想。下面结合代码进行分析:
- 变量说明: 题目中的N在代码中用n表示,题目中的Q在代码中用q表示。一共可以有多次输入(使用while循环表示),当输入的n等于0的时候退出循环。a表示每次输入的最小的图形对应的矩阵,pic用于存放最后的结果的矩阵(根据题意,不会超过3000,需要稍微开大一点,以存放'\0')。
- 主函数main: 首先是一个while循环,然后由于存在多组输入,所以一定要记住每次进入while循环都需要先对a数组和pic数组进行初始化(初始化很重要,尤其是pic,否则会导致后面的输入不正确,注意初始化为' '空格和不初始化即默认初始化为'\0'是不一样的)。
- 递归思想:
- 为什么这题需要用到递归? 因为对于这种模拟图形的问题,我们首先需要找规律。那么仔细观察就会发现,其实最后的输出是有层次的,输出的整个图形是最外层,输入的最小图形是最内层,总共的层次数是q。
- 而对于递归,我们需要写入一个dfs函数(drawDFS),其中传入的参数就有我们对应的层次,当到达最底层(q=1)的时候,我们就要进行输出,但是并非直接输出,而是将其存放在数组pic中,因为直接输出无法得到我们最后想要的效果。(这里q==1,也就是我们平时所说的递归结束条件,一般写在最前面,执行完需要return,不再继续往下递归)
- 执行完q==1以后就会返回上一层,继续执行上一层后面的代码,本题放回到上一层没有剩余代码需要执行。
- 那么除此之外还需要什么参数呢,我们注意到到达最低层(q=1)以后输出的基本图形都是一样的,不同的是起始坐标(左上角坐标),所以还需要引入参数x, y来表示左上角坐标。
- 最开始,初始调用的时候传入的参数为Q=3,x=0,y=0,接下来从最外层开始,注意到有图形还是空格和最小的图形那一个有图形还是空格一一对应。所以当最下层图形没有空格的时候,我们才需要往下递归,层数减去1(Q-1)。
- 可是坐标怎么计算呢? 当不清楚时,最简单的就是对照着输出样例,代数字尝试,当n=3时,对应的最外层的每个小块的左上角坐标时加9(正好为n的(Q-1)次方,即为sz),所以new_x = x + i * sz, new_y = y + j * sz。
题解(递归法)
#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 5;
char a[N][N];
const int M = 3001;
char pic[M][M];
void drawDFS(int Q, int n, int x, int y) {
int sz = pow(n, Q - 1);
if (Q == 1) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
pic[x + i][y + j] = a[i][j];
}
}
}else {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] != ' ') {
drawDFS(Q - 1, n, x + i * sz, y + j * sz);
}
}
}
}
}
int main() {
int n, q;
while(scanf("%d", &n) && n != 0) {
// 每次都要重新初始化
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
a[i][j] = ' ';
}
}
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
pic[i][j] = ' ';
}
}
getchar();
for (int i = 0; i < n; i++) {
scanf("%[^\n]%*c", a[i]);
}
scanf("%d", &q);
int lines = pow(n, q);
drawDFS(q, n, 0, 0);
// puts会自动换行,每个puts为单独一行
for (int i = 0; i < lines; i++) {
pic[i][lines] = '\0';
puts(pic[i]);
}
}
return 0;
}