CCF CSP 201512-3 画图
CCF CSP 201512-3 画图
问题描述
..____.____..____..____...___..
./.___/.___||.._.\|.._.\./._.\.
|.|...\___.\|.|_).|.|_).|.|.|.|
|.|___.___).|..__/|.._.<|.|_|.|
.\____|____/|_|...|_|.\_\\___/.
本题要求编程实现一个用 ASCII 字符来画图的程序,支持以下两种操作:
画线:给出两个端点的坐标,画一条连接这两个端点的线段。简便起见题目保证要画的每条线段都是水平或者竖直的。水平线段用字符 - 来画,竖直线段用字符 | 来画。如果一条水平线段和一条竖直线段在某个位置相交,则相交位置用字符 + 代替。
填充:给出填充的起始位置坐标和需要填充的字符,从起始位置开始,用该字符填充相邻位置,直到遇到画布边缘或已经画好的线段。注意这里的相邻位置只需要考虑上下左右 4 个方向,如下图所示,字符 @ 只和 4 个字符 * 相邻。
.*.
*@*
.*.
输入格式
第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个操作按照数据给出的顺序依次执行。画布最初时所有位置都是字符 .(小数点)。
输出格式
样例输入
1 0 0 B
0 1 0 2 0
1 0 0 A
样例输出
A--A
样例输入
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|...
...+--------+...
................
评测用例规模与约定
解析
填充用深度优先搜索或者广度优先搜索,画线就是一个简单的循环。
一些小陷阱:
1.画线的时候有两种情况,从左往右画和从右往左画。
2.填充成一个字母之后还可以填充成另一个字母。
3.再次画线画到+的时候,不应该覆盖掉。
4.不需要考虑填充的点正好在线的情况。
代码
#include "iostream"
#include "algorithm"
#include "stack" using namespace std; int W, H, N;
char canvas[][]; struct Pos {
int x, y;
Pos(int x_, int y_): x(x_), y(y_) {}
}; void drawLine(int x0, int y0, int x1, int y1)
{
if(y0==y1) // draw horizontal line
{
if(x0>x1) swap(x0, x1);
for(int x=x0; x<=x1; x++)
if(canvas[y0][x] == '|') canvas[y0][x] = '+';
else if(canvas[y0][x] != '+') canvas[y0][x] = '-';
}
else // draw vertical line
{
if(y0>y1) swap(y0, y1);
for(int y=y0; y<=y1; y++)
if(canvas[y][x0] == '-') canvas[y][x0] = '+';
else if(canvas[y][x0] != '+') canvas[y][x0] = '|';
}
} bool legal(int x, int y)
{
return x>= && x<W && y>= && y<H;
} void fill(int x, int y, char c)
{
int dx[] = {, , , -};
int dy[] = {, -, , };
stack<Pos> s;
s.push(Pos(x, y));
canvas[y][x] = c;
while(!s.empty())
{
Pos p = s.top();
s.pop();
for(int i=; i<; i++)
{
Pos np(p.x+dx[i], p.y+dy[i]);
if(legal(np.x, np.y) && canvas[np.y][np.x]!='+' && canvas[np.y][np.x]!='|'
&& canvas[np.y][np.x]!='-' && canvas[np.y][np.x]!=c)
{
canvas[np.y][np.x] = c;
s.push(np);
}
}
}
} int main()
{
cin >> W >> H >> N;
for(int y=; y<H; y++)
for(int x=; x<W; x++)
canvas[y][x] = '.';
for(int n=; n<N; n++)
{
int type;
cin >> type;
int x0, y0, x1, y1;
char c;
if(type==)
{
cin >> x0 >> y0 >> x1 >> y1;
drawLine(x0, y0, x1, y1);
}
else
{
cin >> x0 >> y0 >> c;
fill(x0, y0, c);
}
}
for(int h=H-; h>=; h--)
{
for(int w=; w<W; w++)
cout << canvas[h][w];
cout << endl;
}
}
CCF CSP 201512-3 画图的更多相关文章
- CCF CSP 201409-2 画图
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201409-2 画图 问题描述 在一个定义了直角坐标系的纸上,画一个(x1,y1)到(x2,y ...
- CCF CSP 认证
参加第八次CCF CSP认证记录 代码还不知道对不对,过两天出成绩. 成绩出来了,310分. 100+100+100+10+0: 考试13:27开始,17:30结束,提交第4题后不再答题,只是检查前四 ...
- CCF CSP 201609-2 火车购票
题目链接:http://118.190.20.162/view.page?gpid=T46 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一节车厢有20排.每一排 ...
- CCF CSP 201703-3 Markdown
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201703-3 Markdown 问题描述 Markdown 是一种很流行的轻量级标记语言(l ...
- CCF CSP 201703
CCF CSP 2017·03 做了一段时间的CCF CSP试题,个人感觉是这样分布的 A.B题基本纯暴力可满分 B题留心数据范围 C题是个大模拟,留心即可 D题更倾向于图论?(个人做到的D题基本都是 ...
- CCF CSP 201312-3 最大的矩形
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201312-3 最大的矩形 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i( ...
- CCF CSP 201609-3 炉石传说
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201609-3 炉石传说 问题描述 <炉石传说:魔兽英雄传>(Hearthston ...
- CCF CSP 201403-3 命令行选项
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201403-3 命令行选项 问题描述 请你写一个命令行分析程序,用以分析给定的命令行里包含哪些 ...
- CCF CSP 201709-4 通信网络
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201709-4 通信网络 问题描述 某国的军队由N个部门组成,为了提高安全性,部门之间建立了M ...
随机推荐
- (转)Python中的generator详解
本文转自:http://www.cnblogs.com/xybaby/p/6322376.html 作者:xybaby 注:本文在原文基础上做了一点点修改,仅仅作为个人理解与记忆,建议直接查看原文. ...
- Solr常用命令总结
前提条件: 安装solr版本:4.8.0 部署solr路径:/data/solr-4.8.0 1. 通过zookeeper上传一些配置信息: 通过zk命令将配置信息上传到zk环境中: /data/so ...
- Java6的新特性
原文出处:xixicat 序 本文梳理了下java6的新特性,相对于java5而言,java6的特性显得少些,分量也不那么重,相当于java5是windows xp,java6有点像vista. 特性 ...
- Redis配置及使用
1.参考资料 在线命令说明: http://doc.redisfans.com/ redis安装列表: https://github.com/rgl/redis/downloads Redis工具使用 ...
- Linux基础命令【记录】
后台运行详情:https://www.cnblogs.com/little-ant/p/3952424.html 查看端口.查找等命令 根据关键字查找文件信息: cat <文件名> | g ...
- bzoj千题计划164:bzoj5123: 线段树的匹配
http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf dp[len][0/1] 表示节点表示区间长度为len,节点选/不选的 最大匹配 s ...
- bzoj千题计划112:bzoj1022: [SHOI2008]小约翰的游戏John
http://www.lydsy.com/JudgeOnline/problem.php?id=1022 http://www.cnblogs.com/TheRoadToTheGold/p/67448 ...
- VBS 重启 TP-Link 路由器
分享一个自己用的小工具,重启TP-Link路由器的,好像还是大学时候写的,献丑了. 其他路由器可能有些不同,但是思路都是差不多的. user = "admin" '路由器帐号 pa ...
- 一个diff工具,用于判断两个目录下所有的改动(比较新旧版本文件夹)
需求: 编写一个diff工具,用于判断两个目录下所有的改动 详细介绍: 有A和B两个目录,目录所在位置及层级均不确定 需要以B为基准找出两个目录中所有有改动的文件(文件或内容增加.修改.删除),将有改 ...
- C#利用System.Net发送邮件
啥也不说了,直接上干货 using System.Net.Mail;using System.Net; //使用发送邮件的邮箱 var emailAcount = "826217795@qq ...