所需知识储备
C\C++、bfs\dfs
感想
这个题题意比较明确,不过坑有点儿多,写完代码检查了很多次,但还是扣掉了10分。
发现的坑
- ’+’ 不能被后来画的线覆盖(90分八成这个原因)
- (x,y)对应数组中的[y][x]
- 输出时最外层循环需要倒着来,因为画布左下角是坐标原点
- 划线的时候给的两点的坐标可能是这样(倒着也得能处理):(5,3),(1,3)
- dfs时需要维护一个记录那些点走过,哪些点还没走过(否则死循环)
- 第一个点也需要记录走没走过(虽然不记录问题也不大)
基本思路
该题要求用字符画画,所以,使用一个二维字符数组就可以充当画布。然后就是要实现两种操作,划线和填充。
划线操作相对来说比较简单,因为题目中说明了只有横线和竖线两种情况。分情况处理即可。找到起点和终点(注意起点要小于终点),for循环画线即可,划线是遇到相反的线变’+’,遇到’+'保持不变。
填充操作可以使用深搜(dfs)和广搜(bfs)。需要注意的是,需要维护一个二维数组vis或其他方式来记录每一个点是否被填充过,来保证程序不会陷入死循环。每一次填充之前,都要将vis重置,表示所有点都没有被填充过。
常用技巧
无论是深搜还是广搜,我们都要遍历四个方向,常量数组是个很好的选择,使用它可以极大的简化代码。
int dx[] = {1, 0,-1, 0};
int dy[] = {0, 1, 0,-1};
for(int i=0;i<4;i++) //一个循环轻松遍历上下左右相邻的点
{
if(!vis[y+dy[i]][x+dx[i]])
{
vis[y+dy[i]][x+dx[i]]=1;
tc(x+dx[i], y+dy[i], c);
}
}
完整代码(dfs)
#include<bits\stdc++.h>
using namespace std;
int m, n, q;
char canvas[105][105];
int dx[] = {1, 0,-1, 0};
int dy[] = {0, 1, 0,-1};
int vis[105][105];
void drawLine(int x1, int y1, int x2, int y2)
{
int begin, end;
if(x1 == x2) //画竖线
{
begin = min(y1, y2);
end = max(y1, y2);
for(int i=begin;i<=end;i++)
{
if(canvas[i][x1] == '-') canvas[i][x1] = '+';
else if(canvas[i][x1] == '+') continue;
else canvas[i][x1] = '|';
}
}
else //画横线
{
begin = min(x1, x2);
end = max(x1, x2);
for(int i=begin;i<=end;i++)
{
if(canvas[y1][i] == '|') canvas[y1][i] = '+';
else if(canvas[y1][i] == '+') continue;
else canvas[y1][i] = '-';
}
}
}
bool check(int x, int y)
{
if(x < 0 || x >= m || y < 0 || y >= n) return false;
char c = canvas[y][x];
return (c!='+' && c!='-' && c!= '|');
}
void tc(int x, int y, char c)
{
if(!check(x, y)) return;
canvas[y][x] = c;
for(int i=0;i<4;i++)
{
if(!vis[y+dy[i]][x+dx[i]])
{
vis[y+dy[i]][x+dx[i]]=1;
tc(x+dx[i], y+dy[i], c);
}
}
}
int main ()
{
scanf("%d %d %d", &m, &n, &q);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
canvas[i][j] = '.';
}
}
int op;
for(int i=0;i<q;i++)
{
scanf("%d", &op);
switch(op)
{
case 0:{
int x1, x2, y1, y2;
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
drawLine(x1, y1, x2, y2);
break;
}
case 1:{
int x, y;
scanf("%d %d", &x, &y);
char c;
getchar();
scanf("%c",&c);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
vis[i][j] = 0;
}
}
vis[y][x]=1; /*这里不该少的*/
tc(x,y,c);
break;
}
}
}
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<m;j++)
{
printf("%c", canvas[i][j]);
}
printf("\n");
}
return 0;
}