画家小Q——腾讯2018春招技术类编程题

题目描述

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

输入描述

每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数N和M(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

题目分析

其实这个是根据不同的颜色来推出达到这个颜色的上一步是什么操作,是一个不断回溯的过程,详情请见代码注释。

代码

Java代码如下:

 
 
import java.util.Scanner;

public class Main
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        String cur=scanner.nextLine();
        int n=Integer.valueOf(cur.split(" ")[0]);
        int m=Integer.valueOf(cur.split(" ")[1]);
        char color[][]=new char[n][m];
        for(int i=0;i<n;i++)
        {
            cur=scanner.nextLine();
            for(int j=0;j<cur.length();j++)
            {
                color[i][j]=cur.charAt(j);
            }
        }
        
        //最少的次数
        stepTime(n,m,color);
        //输入结束
        scanner.close();
    }
    //获取最少次数,画一个颜色直到结束为止
    private static void stepTime(int n,int m,char color[][])
    {
        int step=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(color[i][j]=='Y')//画Y
                {
                  drawY(i,j,n,m,color);
                    step++;
                }
                else if(color[i][j]=='B')//画B
                {
                    drawB(i,j,n,m,color);
                    step++;
                }
                else if(color[i][j]=='G')//先画Y再画B
                {
                     drawY(i,j,n,m,color);
                    step++;
                     drawB(i,j,n,m,color);
                    step++;
                    
                    
                }
            }
        }
        System.out.println(step);
    }
    
    //画Y
    private static void drawY(int x,int y,int n,int m,char color[][])
    {
        //判断当前的位置是否能够画Y
        if(x>=0&&x<n&&y>=0&&y<m&&(color[x][y]=='Y'||color[x][y]=='G'))
        {
            
            if(color[x][y]=='G')
            {
                color[x][y]='B';//如果当前位置要画G,那么就是画了Y之后再画个B,上一步就是画B
            }
        else 
        {
            color[x][y]='X';//如果这个位置要画Y,那么画完Y之后就不用再画了,上一步就没有画
        }
          //是否连续的画Y
            drawY(x-1,y-1,n,m,color);//向左上方继续画Y
            drawY(x+1,y+1,n,m,color);//向右下方继续画Y
            
        }
    }
    
      
    //画X
    private static void drawB(int x,int y,int n,int m,char color[][])
    {
        //判断当前的位置是否能够画Y
        if(x>=0&&x<n&&y>=0&&y<m&&(color[x][y]=='B'||color[x][y]=='G'))
        {
            
            if(color[x][y]=='G')
            {
                color[x][y]='Y';//如果当前位置要画G,那么就是画了Y之后只能再画y,上一步就是画Y
            }
        else 
        {
            color[x][y]='X';//如果这个位置要画B,那么画完B之后就不用再画了,上一步就没有画
        }
          //是否连续的画Y
            drawB(x+1,y-1,n,m,color);//向左下方继续画B
            drawB(x-1,y+1,n,m,color);//向右上方继续画B
            
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值