问题描述
试题编号: | 201512-3 |
试题名称: | 画图 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述 用 ASCII 字符来画图是一件有趣的事情,并形成了一门被称为 ASCII Art 的艺术。例如,下图是用 ASCII 字符画出来的 CSPRO 字样。 输入格式 第1行有三个整数m, n和q。m和n分别表示画布的宽度和高度,以字符为单位。q表示画图操作的个数。 输出格式 输出有n行,每行m个字符,表示依次执行这q个操作后得到的画图结果。 样例输入 4 2 3 样例输出 AAAA 样例输入 16 13 9 样例输出 ................ 评测用例规模与约定 所有的评测用例满足:2 ≤ m, n ≤ 100,0 ≤ q ≤ 100,0 ≤ x < m(x表示输入数据中所有位置的x坐标),0 ≤ y < n(y表示输入数据中所有位置的y坐标)。 |
主要完成两个操作,一个操作是画线,一个是填充。
首先画布中元素的位置与平常使用二维数组元素位置的表示方法并不一致,需要转化一下。
由数学关系知,画布中(i,j)在二维数组中应该表示为(n-1-j,i),则x1=x2时在画布中是画竖线,但在二维数组中应该是画横线,y1=y2时同理。
x1=x2时,y1和y2的大小并没有规定,需要判断一下,y1=y2时同理。
用map[i][j]表示画布转化成的二维数组,行为n,列为m
用ishor[i][j]表示map[i][j]是否是竖线的一部分
用isver[i][j]表示map[i][j]是否是横线的一部分
当ishor[i][j]和isver[i][j]都为真是则表示map[i][j]是横线和竖线的交叉点
填充的时候可以用深搜,还需要开个数组isvisit[i][j]表示是否map[i][j]是否被访问过。注意遇到画布边缘或已经画好的线段该方向上的填充结束。填充元素时新的元素会覆盖旧的元素,因此每次填充完一次元素后都要将isvisit初始化为0。
AC代码:
1 #include<iostream> 2 #include<sstream> 3 #include<algorithm> 4 #include<string> 5 #include<cstring> 6 #include<iomanip> 7 #include<vector> 8 #include<cmath> 9 #include<ctime> 10 #include<stack> 11 #include<queue> 12 using namespace std; 13 char map[100][100]; 14 bool ishor[100][100],isver[100][100],isvisit[100][100]; 15 int n,m,dx[4]={-1,1,0,0},dy[4]={0,0,-1,1}; 16 void dfs(int i,int j,char ch) 17 { 18 if(i<0||i>n-1||j<0||j>m-1) return;//遇到边缘 19 if(ishor[i][j]||isver[i][j]) return;//遇到线段 20 if(isvisit[i][j]) return;//填充过 21 map[i][j]=ch; 22 isvisit[i][j]=1; 23 for(int p=0;p<4;p++)//上下左右 24 { 25 int x=i+dx[p],y=j+dy[p]; 26 dfs(x,y,ch); 27 } 28 } 29 int main() 30 { 31 int q;//m是宽度(横坐标),n是高度(纵坐标) 32 cin>>m>>n>>q; 33 memset(ishor,0,sizeof(ishor)); 34 memset(isver,0,sizeof(isver)); 35 memset(isvisit,0,sizeof(isvisit)); 36 for(int i=0;i<n;i++) 37 for(int j=0;j<m;j++) 38 map[i][j]='.'; 39 40 while(q--) 41 { 42 int order; 43 cin>>order; 44 if(order)//填充操作 45 { 46 int a,b;char c; 47 cin>>a>>b>>c; 48 int x=n-1-b,y=a; 49 dfs(x,y,c); 50 memset(isvisit,0,sizeof(isvisit)); 51 } 52 else //画线段的操作,记录下需要画线段的点 53 { 54 int a,b,c,d; 55 cin>>a>>b>>c>>d; 56 int x1=n-1-b,y1=a,x2=n-1-d,y2=c; 57 if(x1==x2)//画横线 58 { 59 for(int i=min(y1,y2);i<=max(y1,y2);i++) 60 ishor[x1][i]=1; 61 } 62 else if(y1==y2)//画竖线 63 { 64 for(int i=min(x1,x2);i<=max(x1,x2);i++) 65 isver[i][y1]=1; 66 } 67 } 68 } 69 70 for(int i=0;i<n;i++)//输出最终结果 71 { 72 for(int j=0;j<m;j++) 73 if(ishor[i][j]&&isver[i][j]) cout<<'+';//交叉点 74 else if(ishor[i][j]) cout<<'-';//横线 75 else if(isver[i][j]) cout<<'|';//竖线 76 else cout<<map[i][j]; 77 cout<<endl; 78 } 79 } 80