CSP2

题目详情

本题要求编程实现一个用 ASCII 字符来画图的程序,支持以下两种操作:
  Ÿ 画线:给出两个端点的坐标,画一条连接这两个端点的线段。简便起见题目保证要画的每条线段都是水平或者竖直的。水平线段用字符 - 来画,竖直线段用字符 | 来画。如果一条水平线段和一条竖直线段在某个位置相交,则相交位置用字符 + 代替。
  Ÿ 填充:给出填充的起始位置坐标和需要填充的字符,从起始位置开始,用该字符填充相邻位置,直到遇到画布边缘或已经画好的线段。注意这里的相邻位置只需要考虑上下左右 4 个方向,如下图所示,字符 @ 只和 4 个字符 * 相邻。
  ..
  @
  .
.
输入格式:
第1行有三个整数m, n和q。m和n分别表示画布的宽度和高度,以字符为单位。q表示画图操作的个数。
  第2行至第q + 1行,每行是以下两种形式之一:
  Ÿ 0 x1 y1 x2 y2:表示画线段的操作,(x1, y1)和(x2, y2)分别是线段的两端,满足要么x1 = x2 且y1 ≠ y2,要么 y1 = y2 且 x1 ≠ x2。
  Ÿ 1 x y c:表示填充操作,(x, y)是起始位置,保证不会落在任何已有的线段上;c 为填充字符,是大小写字母。
  画布的左下角是坐标为 (0, 0) 的位置,向右为x坐标增大的方向,向上为y坐标增大的方向。这q个操作按照数据给出的顺序依次执行。画布最初时所有位置都是字符 .(小数点)。
输出格式:
输出有n行,每行m个字符,表示依次执行这q个操作后得到的画图结果。
样例:
input:
16 13 9
0 3 1 12 1
0 12 1 12 3
0 12 3 6 3
0 6 3 6 9
0 6 9 12 9
0 12 9 12 11
0 12 11 3 11
0 3 11 3 1
1 4 2 C
output:

…±-------+…
…|CCCCCCCC|…
…|CC±----+…
…|CC|…
…|CC|…
…|CC|…
…|CC|…
…|CC|…
…|CC±----+…
…|CCCCCCCC|…
…±-------+…

思路

这里的一个坑就是坐标转换的问题,把二维数组画出来,其(n-1,0)处是原点,向右是x轴变大的方向,就是列索引变大的方向,向上是y轴变大的方向,也是行索引变小的方向,所以决定画横向和画竖线是得多加考虑。对于填充我选择的是bfs方法,这里也要考虑坐标转换,这里将坐标x,y值进行调换就可,再以’|’,’-’,’+'和m,n作为边界条件进行遍历填充,这样操作输出时只需要按行逆序输出即可

代码

#include <bits/stdc++.h>

using namespace std;

struct point
{
	int x;
	int y;
};

point t;
point de[4]={{0,1},{0,-1},{-1,0},{1,0}};
char mp[102][102],c;
bool vis[102][102];
int n,m,q,cz;
int xp1,xp2,yp1,yp2;
queue<point>qe;

bool can(int a,int b)
{
	if(vis[a][b]==1||a<0||a>=m||b<0||b>=n||mp[a][b]=='|'||mp[a][b]=='+'||mp[a][b]=='-')
	return 0;
	return 1;
}
void fill(int a,int b,char c)
{
	memset(vis,0,sizeof(vis)); 
	qe.push({a,b});
	while(!qe.empty())
	{
		t=qe.front();
		qe.pop(); 
		for(int i=0;i<4;i++)
		{
			xp2=t.x+de[i].x;
			yp2=t.y+de[i].y;
			if(can(xp2,yp2))
			{
				vis[xp2][yp2]=1;
				mp[xp2][yp2]=c;
				qe.push({xp2,yp2});
			}
		}
	} 
}
void draw(int a1,int b1,int a2,int b2)
{ 
	if(a1==a2)
	{
        if(b1>=b2)
        {
            int temp=b1;b1=b2;b2=temp;
        }
		for(int i=b1;i<=b2;i++)
		{
			if(mp[i][a1]=='-'||mp[i][a1]=='+')mp[i][a1]='+';
			else mp[i][a1]='|';
		 } 
	}
	else
	{
        if(a1>=a2)
        {
           int temp=a1;
            a1=a2;
            a2=temp;
        }
		for(int i=a1;i<=a2;i++)
		{
			if(mp[b1][i]=='|')mp[b1][i]='+';
			else mp[b1][i]='-';
		} 	
	 } 
}
int main()
{
	scanf("%d%d%d",&m,&n,&q);
     memset(mp,'.',sizeof(mp));
	while(q--)
	{
		scanf("%d",&cz);
		if(cz){ 
		    cin>>xp1>>yp1>>c;
 			fill(xp1,yp1,c);

		}
		else{ 
			cin>>xp1>>yp1>>xp2>>yp2; 
			draw(xp1,yp1,xp2,yp2);		
		}
	}
   
	for(int i=n-1;i>=0;i--)
    for(int j=0;j<m;j++)
	{
		printf("%c",mp[i][j]);
		if(j==m-1)printf("\n");
	} 
	return 0;
}

总结

这个题真的是太绕了,搞得我数组索引,坐标值傻傻分不清,果然画图还是很有用的,判断坐标是否越界时,m和n写反了,搞了好几次的70分,好恶心。

发布了20 篇原创文章 · 获赞 3 · 访问量 455

猜你喜欢

转载自blog.csdn.net/qq_44893580/article/details/104982165
CSP