美文网首页
[42]画家小Q--腾讯2018秋

[42]画家小Q--腾讯2018秋

作者: jdzhangxin | 来源:发表于2018-11-08 19:51 被阅读42次

    1.题目描述

    画家小Q又开始他的艺术创作。小Q拿出了一块有NxM像素格的画板, 画板初始状态是空白的,用'X'表示。
    小Q有他独特的绘画技巧,每次小Q会选择一条斜线, 如果斜线的方向形如'/',即斜率为1,小Q会选择这条斜线中的一段格子,都涂画为蓝色,用'B'表示;如果对角线的方向形如'\',即斜率为-1,小Q会选择这条斜线中的一段格子,都涂画为黄色,用'Y'表示。
    如果一个格子既被蓝色涂画过又被黄色涂画过,那么这个格子就会变成绿色,用'G'表示。
    小Q已经有想画出的作品的样子, 请你帮他计算一下他最少需要多少次操作完成这幅画。

    • 输入描述:
      每个输入包含一个测试用例。
      每个测试用例的第一行包含两个正整数NM(1 <= N, M <= 50), 表示画板的长宽。
      接下来的N行包含N个长度为M的字符串, 其中包含字符'B','Y','G','X',分别表示蓝色,黄色,绿色,空白。整个表示小Q要完成的作品。
    • 输出描述:
      输出一个正整数, 表示小Q最少需要多少次操作完成绘画。
    • 输入示例:
      4 4 
      YXXB 
      XYGX 
      XBYY 
      BXXY
      
    • 输出示例:
      3 
      
    • 说明:
      XXXX 
      XXXX 
      XXXX 
      XXXX 
      -> 
      YXXX 
      XYXX 
      XXYX 
      XXXY 
      -> 
      YXXB 
      XYBX 
      XBYX 
      BXXY 
      -> 
      YXXB 
      XYGX 
      XBYY 
      BXXY
      

    2.题目解析

    只需遍历两边即可:第一次以'\'的方式遍历,第二次以'/'的方式遍历。每次遍历把涂画复原,即

    1. 蓝色'B'和黄色'Y'复原成空白'X'
    2. 绿色'G'复原成蓝色'B'和黄色'Y'。

    统计复原次数,直到所有都变成空白'X'。

    3.参考答案

    #include <bits/stdc++.h>
    using namespace std;
    int n = 0; // 行
    int m = 0; // 列
    char str[50][50];
    void dfs_Y(int x, int y) {
      if (x >= 0 && x < n && y >= 0 && y < m 
         && (str[x][y] == 'Y' || str[x][y] == 'G')) {
        // 清除Y
        if (str[x][y] == 'G')
          str[x][y] = 'B';
        else
          str[x][y] = 'X'; 
        dfs_Y(x - 1, y - 1); // 向左上方遍历
        dfs_Y(x + 1, y + 1); // 向右下方遍历
      }
      return;
    }
    void dfs_B(int x, int y) {
      if (x >= 0 && x < n && 0 <= y && y < m
         && (str[x][y] == 'B' || str[x][y] == 'G')) {
        // 清除B
        if (str[x][y] == 'G')
          str[x][y] = 'Y';
        else
          str[x][y] = 'X';
        dfs_B(x + 1, y - 1); // 向左下方遍历
        dfs_B(x - 1, y + 1); // 向右上方遍历
      }
      return;
    }
    int main() {
      scanf("%d%d", &n, &m);
      for (int i = 0; i < n; i++)
        scanf("%s", str[i]);
      
      int cnt = 0;
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
          if (str[i][j] == 'Y') { // 反斜线
            dfs_Y(i, j);
            cnt++;
          } else if (str[i][j] == 'B') { // 斜线
            dfs_B(i, j);
            cnt++;
          } else if (str[i][j] == 'G') { // 交叉
            dfs_Y(i, j);
            str[i][j] = 'B';
            dfs_B(i, j);
            cnt += 2;
          }
        }
      }
      printf("%d\n", cnt);
      return 0;
    }
    

    下面解答有什么区别?

    #include <iostream>
    using namespace std;
    
    char str[60][60];
    int N, M;
    
    void search_Y(int x, int y) {
      if (x >= 0 && x < N && y >= 0 && y < M &&
          (str[x][y] == 'Y' || str[x][y] == 'G')) {
        if (str[x][y] == 'G')
          str[x][y] = 'B';
        else
          str[x][y] = 'X';
        search_Y(x + 1, y + 1);
      }
      return;
    }
    
    void search_B(int x, int y) {
      if (x >= 0 && x < N && y >= 0 && y < M &&
          (str[x][y] == 'B' || str[x][y] == 'G')) {
        if (str[x][y] == 'G')
          str[x][y] = 'Y';
        else
          str[x][y] = 'X';
        search_B(x + 1, y - 1);
      }
      return;
    }
    
    int main() {
      int res = 0;
      scanf("%d%d", &N, &M);
      for (int i = 0; i < N; ++i)
        scanf("%s", str[i]);
      for (int i = 0; i < N; ++i) {
        for (int j = 0; j < M; ++j) {
          if (str[i][j] == 'Y') {
            search_Y(i, j);
            res++;
          } else if (str[i][j] == 'B') {
            search_B(i, j);
            res++;
          } else if (str[i][j] == 'G') {
            search_Y(i, j);
            res++;
            search_B(i, j);
            res++;
          }
        }
      }
      printf("%d", res);
      return 0;
    }
    

    牛客题目

    相关文章

      网友评论

          本文标题:[42]画家小Q--腾讯2018秋

          本文链接:https://www.haomeiwen.com/subject/ofejoftx.html