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

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

输入描述:
第一行是样例数T(T<9)
第2到2+T-1行每行有一个整数n(n<8),代表lulu听到的数字
输出描述:
听到对应数字时,输出对应样子的圆圈。
示例1
输入
4
0
1
2
3
输出
O
 O
O O
 O
    O
   O O
    O
 O     O
O O   O O
 O     O
    O
   O O
    O
             O
            O O
             O
          O     O
         O O   O O
          O     O
             O
            O O
             O
    O                 O
   O O               O O
    O                 O
 O     O           O     O
O O   O O         O O   O O
 O     O           O     O
    O                 O
   O O               O O
    O                 O
             O
            O O
             O
          O     O
         O O   O O
          O     O
             O
            O O
             O
说明
当n=0时输出
O
当n=1时输出
*O
O*O
*O
当n=2时输出
****O
***O*O
****O
*O*****O
O*O***O*O
*O*****O
****O
***O*O
****O
上面的'O'是大写英文字母O,'*'代表空格,每一行最后一个O后面不带空格。
备注:
对于100%的数据,
0<T<9;
0<=n<8;
找到规律,可以每次找到单位菱形的中心点,然后由中心点向四周扩散,比如(1,1) 对应的菱形中心点是(2,2)。(2,2)这个坐标扩散之后是(1,2),(3,2),(2,1),(2,3)。然后再由这四个坐标继续对应四个菱形的中心点,即(2,5),(8,5),(5,2),(5,8),可以发现(x,y)对应的单位菱形的中心点是(3*x-1, 3*y-1),依次循环。将坐标存下来,最后以字符形式输出。可以发现每次输出的行和列都相等,为3^x。然后需要注意一下格式,不要输出多于的空格。具体请看代码。
#include <stdio.h>
#include <string.h>
int d[4][2] = {1, 0, -1, 0, 0, -1, 0, 1};
int a[8];//存每个坐标的个数 
struct node{
    int x, y;
}s[8][25000];//存坐标 
int b[2500]; //控制空格 
char c[2500][2500];
int mul(int x) { //得到3^x
    int sum = 1;
    for(int i = 1; i <= x; i++) {
    	sum *= 3;
	} 
    return sum;
}
int main() {
    s[0][1].x = 1;//初始坐标 
    s[0][1].y = 1;
    a[0] = 2;
    for(int i = 1; i < 8; i++) {
        int p = 1;//坐标个数 
        for(int j = 1; j < a[i-1]; j++) {
            int x = 3*s[i-1][j].x-1;//得到菱形的中心点坐标 
            int y = 3*s[i-1][j].y-1;
            for(int k = 0; k < 4; k++) {//得到上下左右的坐标 
                int dx = d[k][0] + x;
                int dy = d[k][1] + y;
                s[i][p].x = dx;
                s[i][p].y = dy;
                p++;
            }
        }
        a[i] = p;   //将坐标的数量赋值给a[i] 
    }
    int T;
    int n;
    scanf("%d", &T);
    while(T--) {
        memset(c, ' ', sizeof(c));
        memset(b, 0, sizeof(b));
        scanf("%d", &n);
        for(int i = 1; i < a[n]; i++) {
            c[s[n][i].x][s[n][i].y] = 'O';
            if(b[s[n][i].x] < s[n][i].y) //找到最右边的'O',以便控制空格输出 
            b[s[n][i].x] = s[n][i].y;
        }
        for(int i = 1; i <= mul(n); i++) {//输出 
            for(int j = 1; j <= mul(n); j++) {
                if(c[i][j] == 'O') printf("O");
                else printf(" ");
                if(j == b[i]) break;
            }
            printf("\n");
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值