2018年全国多校算法寒假训练营练习比赛(第一场)G 圆圈

时间:2021-09-21 00:19:08

链接:https://www.nowcoder.com/acm/contest/67/G

来源:牛客网

题目描述

    圈圈圆圆圈圈,lulu小朋友最近看喜羊羊看多了,老是受刺激就画圆圈,听到小于8的数字时,还会画出十分有规律的圆圈,现在你需要根据样例观察出规律,编写程序,根据输入的数字n(n<8),输出对应的圆圈。

输入描述:

第一行是样例数T(T<9)
第2到2+T-1行每行有一个整数n(n<8),代表lulu听到的数字

输出描述:

听到对应数字时,输出对应样子的圆圈。
题目类型是分形,规律相对比较直观。

用递归来做比较简单: 当要打印 f(n) 的时候,其实就是打印:

空格    f(n-1)

f(n-1)空格 f(n-1)

空格    f(n-1)

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

// topsp[i] 存放第i-1个图形的矩阵宽度
// 比如 topsp[2] = 3 则说明 f(1)是个3*3的图形
int topsp[10] = { 0, 1 };
char ans[2500][2500];

// 打印 f(n) 这个图形的左上角坐标是(x,y)
void show( int n, int x, int y )
{
if( n == 0 ) {ans[x][y]='O';return;}

show(n-1,x, y+topsp[n]);

show(n-1,x+topsp[n], y);
show(n-1,x+topsp[n], y+(topsp[n]<<1));

show(n-1,x+(topsp[n]<<1), y+topsp[n]);
}

int main()
{
for ( int i = 2 ; i < 10 ; ++ i ) {
topsp[i] = topsp[i-1]*3;
}
int T, n;
scanf( "%d", &T );
while ( T -- ) {
scanf( "%d", &n );
if( n == 0 ) {putchar('O');continue;}
memset(ans, 0, sizeof(ans));
show(n, 0, 0);
for ( int i = 0 ; i < topsp[n]*3 ; ++ i ) {
int k = topsp[n]*3;
// 找到最后一个O
while ( ans[i][k] != 'O' ) k--;
for ( int j = 0 ; j <= k ; ++ j ) {
if ( ans[i][j] != 'O' ) putchar(' ');
else putchar('O');
}
puts("");
}
}
return 0;
}