边长与点数-离散点阵的基本计算规律
下面是一个蓝桥杯的真题,不过很水,是找规律的题目。
小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示:
对方同时也需要在电脑dos窗口中以字符的形式输出该标志,并能任意控制层数。
上图是一个三层的标志。起始这个图形的每一次加入的边框很类似红十字会的标志。我的思路是从每一层边框的第一行的最左端的$开始绘制。对于同一层边框里的边来说,利用循环同时绘制所有的平行且边长相等的边。这样,只需要四次循环就可完成一层的绘制。每一次的绘制信息封装在solve()函数中,并向内传入起始点坐标与该层的最大边长。我发现,对于n层图,输入的边长为4n+9。另外,正中心的十字采用从中心点出发向四个方向各绘制2个点的方式完成。矩阵采用int数组初始化为0,对于每一个$符号用1代替。最终输出时进行转换即可。下面是我的代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 using namespace std; 5 int aim[150][150]; 6 int n; 7 8 int solve(int x,int y,int L) 9 { 10 for(int i=1;i<=L-4;i++) 11 { 12 aim[x][y]=1; 13 aim[x+L-1][y]=1; 14 y++; 15 } 16 y--; 17 for(int i=1;i<=3;i++) 18 { 19 aim[x][y]=1; 20 aim[x][y-(L-4)+1]=1; 21 aim[x+(L-4)+1][y]=1; 22 aim[x+(L-4)+1][y-(L-4)+1]=1; 23 x++; 24 } 25 x--; 26 for(int i=1;i<=3;i++) 27 { 28 aim[x][y]=1; 29 aim[x][y-(L-4)-1]=1; 30 aim[x+(L-4)-1][y]=1; 31 aim[x+(L-4)-1][y-(L-4)-1]=1; 32 y++; 33 } 34 y--; 35 for(int i=1;i<L-4;i++) 36 { 37 aim[x][y]=1; 38 aim[x][y-L+1]=1; 39 x++; 40 }/**/ 41 return 0; 42 } 43 44 const int dx[]={0,0,0,0,0,1,2,-1,-2}; 45 const int dy[]={0,1,2,-1,-2,0,0,0,0}; 46 47 int main() 48 { 49 memset(aim,0,sizeof(aim)); 50 cin>>n; 51 int x=0,y=2; 52 for(int pn=n;pn>=1;x+=2,y+=2,pn--) 53 { 54 solve(x,y,4*pn+5); 55 } 56 // 57 int L=4*n+5; 58 int px=L/2,py=L/2; 59 for(int i=0;i<9;i++)aim[px+dx[i]][py+dy[i]]=1; 60 // 61 for(int i=0;i<L;i++) 62 { 63 for(int k=0;k<L;k++) 64 { 65 if(aim[i][k])printf("$"); 66 else printf("."); 67 } 68 printf("\n"); 69 } 70 return 0; 71 }
题目不难,但是在调试过程中对点的个数与边的长度判断上有较大麻烦。主要表现在solve函数中每一个循环内的赋值过程。
对于n个点形成的一条点线,其点长度为n,第p个点和第q个点之间存在|p-q|-1个点。
如果点的个数相差真的很不好确定,则可以分布调试。具体步骤是写完solve函数的一个循环后,将n设为1(只对一层图进行调试),先进行输出图案,显示并调试。千万不要一口气写完所有循环后又同时调试。
下面是上述代码的运行结果(结果来自蓝桥网训练系统):
打印十字图 | 03-02 23:22 | 999B | C++ | 正确 | 100 | 0ms | 2.617MB |
OK