• CCF-CSP201512-3 画图


    题目链接

    问题描述

    试题编号: 201512-3
    试题名称: 画图
    时间限制: 1.0s
    内存限制: 256.0MB
    问题描述:

    问题描述

      用 ASCII 字符来画图是一件有趣的事情,并形成了一门被称为 ASCII Art 的艺术。例如,下图是用 ASCII 字符画出来的 CSPRO 字样。
      ..____.____..____..____...___..
      ./.___/.___||.._.|.._../._..
      |.|...\___.|.|_).|.|_).|.|.|.|
      |.|___.___).|..__/|.._.<|.|_|.|
      .\____|____/|_|...|_|.\_\___/.
      本题要求编程实现一个用 ASCII 字符来画图的程序,支持以下两种操作:
       画线:给出两个端点的坐标,画一条连接这两个端点的线段。简便起见题目保证要画的每条线段都是水平或者竖直的。水平线段用字符 - 来画,竖直线段用字符 | 来画。如果一条水平线段和一条竖直线段在某个位置相交,则相交位置用字符 + 代替。
       填充:给出填充的起始位置坐标和需要填充的字符,从起始位置开始,用该字符填充相邻位置,直到遇到画布边缘或已经画好的线段。注意这里的相邻位置只需要考虑上下左右 4 个方向,如下图所示,字符 @ 只和 4 个字符 * 相邻。
      .*.
      *@*
      .*.

    输入格式

      第1行有三个整数mnqmn分别表示画布的宽度和高度,以字符为单位。q表示画图操作的个数。
      第2行至第q + 1行,每行是以下两种形式之一:
       0 xyxy2:表示画线段的操作,(x1, y1)和(x2, y2)分别是线段的两端,满足要么x1 = x2 且y1 ≠ y2,要么 y1 = y2 且 x1 ≠ x2。
       1 x y c:表示填充操作,(xy)是起始位置,保证不会落在任何已有的线段上;c 为填充字符,是大小写字母。
      画布的左下角是坐标为 (0, 0) 的位置,向右为x坐标增大的方向,向上为y坐标增大的方向。这q个操作按照数据给出的顺序依次执行。画布最初时所有位置都是字符 .(小数点)。

    输出格式

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

    样例输入

    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|...
    ...+--------+...
    ................

    评测用例规模与约定

      所有的评测用例满足:2 ≤ mn ≤ 100,0 ≤ q ≤ 100,0 ≤ x < mx表示输入数据中所有位置的x坐标),0 ≤ y < ny表示输入数据中所有位置的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  
    View Code
  • 相关阅读:
    五、MapReduce 发布服务
    四、MapReduce 基础
    三、Hadoop 的 API
    二、HDFS 架构
    php身份证号的验证
    php性能优化
    PHP网站开发方案
    php一个不错的分页
    2013年最流行的php框架盘点
    程序员之路
  • 原文地址:https://www.cnblogs.com/wangzhebufangqi/p/12796136.html
Copyright © 2020-2023  润新知