素数螺旋
题目描述
绘制一个逆时钟的螺旋线,一开始方向向右,边长依次为第i个素数,即2,3,5,7,⋯ 。 使用
_表示横线,|表示竖线,要求图形的每行行尾无多余的空格。比如n=5时,
_____ | | | | | __| | | | |___________输入格式
第一行是一个整数T (1≤T≤20),表示样例的个数。
以后每行一个整数n(1≤n≤168)。
输出格式
依次按要求输出对应的图形。每个样例之后输出一个空行。
样例输入
4 1 2 3 4样例输出
__ | | __| _____ | | __| _____ | | | | | __| | | | |提示
第168个素数是997。
解题思路: 如果按照以往的找规律然后 从左到右,从上到下依次打印的方法去思考,这道题或许有点难。我们就纯粹的按题目所给的方法模拟,逆时针记录好图像,最后再打印。这样会简单很多。
1. 定制一个 2000*2000的字符数组,从(1000,1000)开始素数螺旋的起点,(开始设置为 1001,999 是为了和42/43行以及打印左边框的代码配合,如果不理解可以先从 1000,1000 模拟一遍,令n==5)。
2. 选定好起点之后就非常容易了, 我们在大脑中将如何逆时针打印图像的步骤过一遍,所想到的步骤即是程序实现的方法。
3. 虽然我们画图的时候是逆时针画出去的,但是打印的时候还是要按从左上到右下的顺序打印,所以我们记录一个整个图像的边框极限,上下左边框极限是根据整个图形判定的,右边框每一行都可能不一样(行末无多余空格)。打印右边框时要更新 上极限(ups),打印上边框时要更新左极限(lefts),打印左边框时要更新 下极限(downs)。 tags 数组记录每一行的右极限。
代码写的有些麻烦,但是思路一点不难。思路一下可能也不能把所以疑点都理清。如果还有疑问且想要弄明白的同学,请按照代码思路模拟一遍,肯定就能弄懂(或者评论留言)。
AC代码:
#include <stdio.h>
bool flag;
int ups,downs,lefts,stx,sty;
int cnt = 1;
int prime[200];
char maps[2000][2000];
void isPrime()
{
for (int i = 2; i <= 1000; i ++)
{
flag = true;
for (int j = 2; j*j <= i; j ++)
{
if (i%j == 0)
{
flag = false;
break;
}
}
if (flag) prime[cnt++] = i;
}
}
void drawmap()
{
for (int i = 0; i < 2000; i ++)
for (int j = 0; j < 2000; j ++)
maps[i][j] = ' ';
}
void draw(int n)
{
ups = 1000,downs = 1000,lefts = 1000; // 螺旋 上下边框极限坐标
stx = 1001,sty = 999; // x为行,y为列
int tags[2000] = {0}; // 螺旋 右边框极限坐标
for (int i = 1; i <= n; i ++)
{
if (i % 4 == 1) // 打印下边框
{
stx --;
sty ++;
for (int j = 1; j <= prime[i]; j ++)
{
maps[stx][sty] = '_';
sty ++;
}
tags[stx] = sty;
}
else if (i % 4 == 2) // 打印右边框
{
for (int j = 1; j <= prime[i]; j ++)
{
maps[stx][sty] = '|';
tags[stx] = sty+1;
stx --;
}
if (i == n) ups = stx + 1;
else ups = stx;
}
else if (i % 4 == 3) // 打印上边框
{
tags[stx] = sty;
sty --;
for (int j = 1; j <= prime[i]; j ++)
{
maps[stx][sty] = '_';
sty --;
}
if (i == n) lefts = sty + 1;
else lefts = sty;
}
else // 打印左边框
{
stx ++;
for (int j = 1; j <= prime[i]; j ++)
{
maps[stx][sty] = '|';
if (tags[stx] == 0)
tags[stx] = sty + 1;
stx ++;
}
downs = stx - 1;
}
}
// 打印
for (int i = ups; i <= downs; i ++)
{
for (int j = lefts; j < tags[i]; j ++)
printf("%c",maps[i][j]);
puts("");
}
puts("");
}
int main()
{
isPrime(); // 这么几个素数,这次就不用欧拉筛了
drawmap();
int T,n;
scanf ("%d",&T);
while ( T -- )
{
scanf("%d",&n);
draw(n);
}
return 0;
}
本文介绍了一种编程方法,通过逆时针模拟生成一个逆时针的素数螺旋线图形,利用C++编写代码实现了从输入的整数n生成对应样例的螺旋图案,重点在于理解逆时针打印和边界处理的思路。
379

被折叠的 条评论
为什么被折叠?



