AcWing 3224. 画图 (BFS,Flood Fill,坐标变换)

2024-03-22 23:20

本文主要是介绍AcWing 3224. 画图 (BFS,Flood Fill,坐标变换),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

用 ASCII 字符来画图是一件有趣的事情,并形成了一门被称为 ASCII Art 的艺术。

例如,下图是用 ASCII 字符画出来的 CSPRO 字样。

  ..____.____..____..____...___.../.___/.___||.._.\|.._.\./._.\.|.|...\___.\|.|_).|.|_).|.|.|.||.|___.___).|..__/|.._.<|.|_|.|.\____|____/|_|...|_|.\_\\___/.

本题要求编程实现一个用 ASCII 字符来画图的程序,支持以下两种操作:

  • 画线:给出两个端点的坐标,画一条连接这两个端点的线段。简便起见题目保证要画的每条线段都是水平或者竖直的。水平线段用字符 -来画,竖直线段用字符 |来画。如果一条水平线段和一条竖直线段在某个位置相交,则相交位置用字符 +代替。
  • 填充:给出填充的起始位置坐标和需要填充的字符,从起始位置开始,用该字符填充相邻位置,直到遇到画布边缘或已经画好的线段。注意这里的相邻位置只需要考虑上下左右 4 4 4 个方向,如下图所示,字符 @只和 4 4 4 个字符 *相邻。
  .*.*@*.*.

输入格式
1 1 1 行有三个整数 m , n m,n m,n q q q m m m n n n 分别表示画布的宽度和高度,以字符为单位。 q q q 表示画图操作的个数。

2 2 2 行至第 q + 1 q+1 q+1 行,每行是以下两种形式之一:

0 x1 y1 x2 y2:表示画线段的操作, ( x 1 , y 1 ) (x1,y1) (x1,y1) ( x 2 , y 2 ) (x2,y2) (x2,y2) 分别是线段的两端,满足要么 x 1 = x 2 x1=x2 x1=x2 y 1 ≠ y 2 y1≠y2 y1=y2,要么 y 1 = y 2 y1=y2 y1=y2 x 1 ≠ x 2 x1≠x2 x1=x2
1 x y c:表示填充操作, ( x , y ) (x,y) (x,y) 是起始位置,保证不会落在任何已有的线段上; c c c 为填充字符,是大小写字母。画布的左下角是坐标为 ( 0 , 0 ) (0,0) (0,0) 的位置,向右为 x x x 坐标增大的方向,向上为 y y y 坐标增大的方向。

q q q 个操作按照数据给出的顺序依次执行。画布最初时所有位置都是字符 .(小数点)。

输出格式
输出有 n n n 行,每行 m m m 个字符,表示依次执行这 q q q 个操作后得到的画图结果。

数据范围
2 ≤ m , n ≤ 100 , 2≤m,n≤100, 2m,n100
0 ≤ q ≤ 100 , 0≤q≤100, 0q100
0 ≤ x < m 0≤x<m 0x<m x x x 表示输入数据中所有位置的 x x x 坐标),
0 ≤ y < n 0≤y<n 0y<n y y y 表示输入数据中所有位置的 y y y 坐标)。

输入样例1:

4 2 3
1 0 0 B
0 1 0 2 0
1 0 0 A

输出样例1:

AAAA
A--A

输入样例2:

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

输出样例2:

................
...+--------+...
...|CCCCCCCC|...
...|CC+-----+...
...|CC|.........
...|CC|.........
...|CC|.........
...|CC|.........
...|CC|.........
...|CC+-----+...
...|CCCCCCCC|...
...+--------+...
................

一道Flood Fill题,但是本题难点在于对于坐标的处理,题目要求的坐标是数学坐标,而编程语言中的坐标并不与其相同,主要区别如下:
在这里插入图片描述
那么这里就分化出了两种做法:直接想办法把二维数组的坐标表示转化为按照题目给出的数学坐标或是把不改变二维数组坐标转而改变读入的坐标与输出的坐标。

当然二者中后者更为简单,本人采用前者频频错误,且本题难以Debug。
故采用后者。
首先在读入中,如果把 x x x y y y 对应的坐标交换读入,那么就会获得类似于这样的坐标存储:
在这里插入图片描述
处于题目要求我们输出时要让他像是数学坐标一样,那么就可以让 x x x 轴倒着输出。

#include<iostream>
#include<queue>
using namespace std;
const int N = 110;
#define pii pair<int,int>
#define x first
#define y second
const int dx[4] = { 1,0,-1,0 };
const int dy[4] = { 0,1,0,-1 };char g[N][N];
int n, m, q;int main() {cin >> m >> n >> q;for (int i = 0; i < n; i++) {		//先初始化for (int j = 0; j < m; j++) {g[i][j] = '.';}}while (q--) {int op;cin >> op;if (op == 0) {	//划线操作int x1, y1, x2, y2; cin >> y1 >> x1 >> y2 >> x2;//倒着读x,yif (x1 == x2) {for (int i = min(y1, y2); i <= max(y1, y2); i++) {if (g[x1][i] == '|' || g[x1][i] == '+')g[x1][i] = '+';	//重点注意'+'也要判断else g[x1][i] = '-';}}else {for (int i = min(x1, x2); i <= max(x1, x2); i++) {if (g[i][y1] == '-' || g[i][y1] == '+')g[i][y1] = '+';else g[i][y1] = '|';}}}else {int x1, y1; char c; cin >> y1 >> x1 >> c;auto bfs = [&]() {	//Flood Fill过程queue<pii>q;q.push({ x1,y1 });g[x1][y1] = c;while (q.size()) {auto t = q.front();q.pop();for (int i = 0; i < 4; i++) {int xx = t.x + dx[i], yy = t.y + dy[i];if (xx >= 0 && xx < n && yy >= 0 && yy < m) {if (g[xx][yy] == '+' || g[xx][yy] == '-' || g[xx][yy] == '|')continue;if (g[xx][yy] == c)continue;g[xx][yy] = c;q.push({ xx,yy });}}}};bfs();}}for (int i = n - 1; i >= 0; i--) {	//由于题目要求原因最后要倒着输出for (int j = 0; j < m; j++) {cout << g[i][j];}puts("");}return 0;
}

这篇关于AcWing 3224. 画图 (BFS,Flood Fill,坐标变换)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836414

相关文章

hdu1254(嵌套bfs,两次bfs)

/*第一次做这种题感觉很有压力,思路还是有点混乱,总是wa,改了好多次才ac的思路:把箱子的移动当做第一层bfs,队列节点要用到当前箱子坐标(x,y),走的次数step,当前人的weizhi(man_x,man_y),要判断人能否将箱子推到某点时要嵌套第二层bfs(人的移动);代码如下:

poj 2195 bfs+有流量限制的最小费用流

题意: 给一张n * m(100 * 100)的图,图中” . " 代表空地, “ M ” 代表人, “ H ” 代表家。 现在,要你安排每个人从他所在的地方移动到家里,每移动一格的消耗是1,求最小的消耗。 人可以移动到家的那一格但是不进去。 解析: 先用bfs搞出每个M与每个H的距离。 然后就是网络流的建图过程了,先抽象出源点s和汇点t。 令源点与每个人相连,容量为1,费用为

POJ 3057 最大二分匹配+bfs + 二分

SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

深度优先(DFS)和广度优先(BFS)——算法

深度优先 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支,当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访

Verybot之OpenCV应用二:霍夫变换查找圆

其实我是想通过这个程序来测试一下,OpenCV在Verybot上跑得怎么样,霍夫变换的原理就不多说了,下面是程序: #include "cv.h"#include "highgui.h"#include "stdio.h"int main(int argc, char** argv){cvNamedWindow("vedio",0);CvCapture* capture;i

SW - 引入第三方dwg图纸后,修改坐标原点

文章目录 SW - 引入第三方dwg图纸后,修改坐标原点概述笔记设置图纸新原点END SW - 引入第三方dwg图纸后,修改坐标原点 概述 在solidworks中引入第三方的dwg格式图纸后,坐标原点大概率都不合适。 全图自动缩放后,引入的图纸离默认的原点位置差很多。 需要自己重新设置原点位置,才能自动缩放后,在工作区中间显示引入的图纸。 笔记 将dwg图纸拖到SW中

【AcWing】851. 求最短路

spfa算法其实是对贝尔曼福特算法做一个优化。 贝尔曼福特算法会遍历所有边来更新,但是每一次迭代的话我不一定每条边都会更新,SPFA是对这个做优化。 如果说dist[b]在当前这次迭代想变小的话,那么一定是dist[a]变小了,只有a变小了,a的后继(b)才会变小。 用宽搜来做优化,用一个队列,队列里边存的就是所有变小了的结点(队列里存的是待更新的点)。 基本思路就是我更新过谁,我再拿

Windows11电脑上自带的画图软件修改照片大小(不裁剪尺寸的情况下)

针对一张图片,有时候上传的图片有大小限制,那么在这种情况下如何修改其大小呢,在不裁剪尺寸的情况下 步骤如下: 1.选定一张图片,右击->打开方式->画图,如下: 第二步:打开图片后,我们可以看到图片的大小为82.1kb,点击上面工具栏的“重设大小和倾斜”进行调整,如下: 第三步:修改水平和垂直的数字,此处我修改为分别都修改为50,然后保存,可以看到大小变成63.5kb,如下:

双头BFS

牛客月赛100 D题,过了80%数据,调了一下午。。。烦死了。。。 还是没调试出来,别人的代码用5维的距离的更新有滞后性,要在遍历之前要去重。。。 #include<bits/stdc++.h>using namespace std;const int N=2e3+10;char g[N][N];int dis[N][N],d1[N][N];int n,m,sx,sy;int dx