xtu1441 素数螺旋

 

 

素数螺旋

Submit Code ] [ Top 20 Runs ] [ Runs Status ]
Acceteped : 68 Submit : 520
Time Limit : 1000 MS Memory Limit : 65536 KB
 

Description

素数螺旋

题目描述

绘制一个逆时钟的螺旋线,一开始方向向右,边长依次为第i个素数,即2,3,5,7,⋯ 。 使用_ 表示横线,| 表示竖线,要求图形的每行行尾无多余的空格。

比如n=5时,

 _____
|     |
|     |
|   __|
|
|
|
|___________

输入格式

第一行是一个整数T (1≤T≤20),表示样例的个数。

以后每行一个整数n(1≤n≤168)。

输出格式

依次按要求输出对应的图形。每个样例之后输出一个空行。

样例输入

4
1
2
3
4

样例输出

__

  |
  |
__|

_____
     |
     |
   __|

 _____
|     |
|     |
|   __|
|
|
|
|

提示

第168个素数是997。

 

Sample Input

 
 

Sample Output

 
 

Source

Source Code

Problem: 1441		User: 202205567311
Memory: 25644K		Time: 388MS
Language: G++		Result: Accepted
Source Code

#include <stdio.h>
#include <string.h>
char map[5000][5000]; //中心为2500,2500
int ioprime[1001] = {1, 1};
int prime[170];
int pointx, pointy, point, maxx, maxy, minx, miny, n;//pointx,y,point分别存x轴y轴坐标和方向,min,max分别存上下界
void draw(int sushu)
{ // 1,2,3,4分别对应上左下右从右边开始

    switch (point)
    {
    case 1:
        for (int i = 0; i < sushu; i++)
        {
            map[pointx][pointy] = '|';
            pointx--;
        }
        pointy--;
//向上打印后要左移一个位置
        point = 2;//转向
        break;
    case 2:
        for (int i = 0; i < sushu; i++)
        {
            map[pointx][pointy] = '_';
            pointy--;
        }
        pointx++;//向左打印后直接下移一个位置
        point = 3;
        break;
    case 3:
        for (int i = 0; i < sushu; i++)
        {
            map[pointx][pointy] = '|';
            pointx++;
        }
        pointx--;
        pointy++;//横着的与竖着的同行,所以x--移回去
        point = 4;
        break;
    case 4:
        for (int i = 0; i < sushu; i++)
        {
            map[pointx][pointy] = '_';
            pointy++;
        }
        point = 1;//接着向上打印
        break;
    }
    maxx = (pointx > maxx) ? pointx : maxx;
    maxy = (pointy > maxy) ? pointy : maxy;
    minx = (pointx < minx) ? pointx : minx;
    miny = (pointy < miny) ? pointy : miny;//实时更新边界
}
void print(void)
{
    int i, j;
    char *arrey = NULL;
    if (point == 3)
    {
        miny++;
    }
    if(point==2){
        minx++;
    }//把打印时的偏移量移回去。解释一下,因为是先打印在移动,所以必然存在移动而未打印
    for (i = minx; i <= maxx; i++)
    {
    
        for (j =maxy+10; j >= miny; j--)
        {
            if (map[i][j] != ' ')
            {
                map[i][j + 1] = '\0';//这个循环非常重要,从边界开始向左扫描,遇到第一个边界的话就把它右边变成\0,\0作为printf打印的终止符,要不然会PE,输出了多余的空格
                break;
            }
            
        }

        arrey = &map[i][miny];//这个是我在思索如何从某个位置开始打印的时候发现的,数组名在传入函数时是将其指向第一个元素的指针传入,所以我们只需要把指向我们要打印的第一个元素的指针传入就可以实现定点打印的结果
        printf("%s\n", arrey);//以指针指向的第一个元素开始打印,一直到\0结束
    }
}

int main()
{
    int i, j;
    for (i = 2; i * i <= 1001; i++)
    {
        if (!ioprime[i])
        {
            for (j = i * i; j <= 1001; j += i)
            {
                ioprime[j] = 1;
            }
        }
    }
    int countt = 0;
    for (i = 2; i < 1001; i++)
    {
        if (!ioprime[i])
        {
            prime[countt] = i;
            countt++;
        }
    }
//打个素表先
    int t;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        memset(map, ' ', sizeof map);//初始化为空格方便打印
        pointx = 2500, pointy = 2500, point = 4;//中心点
        maxx = 2500, maxy = 2500, minx = 2500, miny = 2500;
        for (i = 0; i < n; i++)
        {
            draw(prime[i]);//从素数表取素数打印
        }

        print();
        putchar('\n');//记得还有一个换行
    }
}

幸亏在想如何打印时想起来了printf传入指针打印字符串的机制,要不然真的不会写了oops~

所以记得把基础打牢,要不然真的会寄的 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值