画图
传送门:http://118.190.20.162/view.page?gpid=T35
题目
样例
样例输入
4 2 3
1 0 0 B
0 1 0 2 0
1 0 0 A
样例输出
AAAA
A–A
样例输入
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
样例输出
…
…±-------+…
…|CCCCCCCC|…
…|CC±----+…
…|CC|…
…|CC|…
…|CC|…
…|CC|…
…|CC|…
…|CC±----+…
…|CCCCCCCC|…
…±-------+…
…
题解思路
csp的第三题是一道大模拟,跟着题意走就行了,没有什么特别的方法(大佬忽略)。
两个函数,一个画线一个填充:
画线时如果当前位置已经有线了或者是已经有+,就画+,其他情况就画指定方向的线。
填充时用递归遍历,向四个方向dfs,遇到线或+或者是已访问过就跳过。
思路比较简单,不过要完成这题的关键点是坐标的转换。我们在开数组的时候通常是左上角为(0,0),而在画布上,左下角才是“原点”,所以纵坐标需要转换。
完整代码
#include <iostream>
#include <string.h>
#include <cmath>
using namespace std;
char c[110][110];
int m, n, q;
int cnt = 0;
void line(int x1, int y1, int x2, int y2)
{
if(x1 == x2)
{
int y3 = min(y1, y2);
int y4 = max(y1, y2);
for(int j=y3;j<=y4;j++)
{
if(c[j][x1] == '-' || c[j][x1] == '+')
{
c[j][x1] = '+';
}
else
{
c[j][x1] = '|';
}
}
}
else if(y1 == y2)
{
int x3 = min(x1, x2);
int x4 = max(x1, x2);
for(int i=x3;i<=x4;i++)
{
if(c[y1][i] == '|' || c[y1][i] == '+')
{
c[y1][i] = '+';
}
else
{
c[y1][i] = '-';
}
}
}
return;
}
void fill(int x, int y, char cc)
{
if(x<0 || y<0 || x>=m || y>=n || c[y][x] == '|' || c[y][x] == '-' || c[y][x] == '+' || c[y][x] == cc)
{
return;
}
c[y][x] = cc;
fill(x, y+1, cc);
fill(x, y-1, cc);
fill(x+1, y, cc);
fill(x-1, y, cc);
return;
}
void Print()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cout<<c[i][j];
}
cout<<endl;
}
}
int main()
{
cin>>m>>n>>q;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
c[i][j] = '.';
}
}
for(int i=0;i<q;i++)
{
int k;
cin>>k;
if(k == 0)
{
int fx1, fy1, fx2, fy2;
cin>>fx1>>fy1>>fx2>>fy2;
int y1, y2;
y1 = n - 1 - fy1;
y2 = n - 1 - fy2;
line(fx1, y1, fx2, y2);
}
else if(k == 1)
{
int fx, fy, y;
char cc;
cin>>fx>>fy>>cc;
y = n - 1 - fy;
fill(fx, y, cc);
}
}
Print();
return 0;
}