画家小Q

 

链接:https://www.nowcoder.com/questionTerminal/6acc6504df67406c98a75f5575e4b94a?orderByHotValue=1&page=1&onlyReference=false
来源:牛客网

画家小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最少需要多少次操作完成绘画。

示例1

输入

4 4
YXXB
XYGX
XBYY
BXXY

输出

3

说明

XXXX
XXXX
XXXX
XXXX
->
YXXX
XYXX
XXYX
XXXY
->
YXXB
XYBX
XBYX
BXXY
->
YXXB
XYGX
XBYY
BXXY

 

先上解题思路,感觉这个人题其实也不难,就是很烦人,比如一笔“\”,画成

YXXX

XYXX

XXYX

XXXY

也好,这算是一笔。

要是画成

YXXX

XXXX

XXYX

XXXY那就算是两笔。

看了一些其他人写的答案,我仔细仔细想了一下这个题,这个题最烦的地方可能就是这个矩阵,没办法横着查或者竖着查,只能斜着查,中间还要考虑断开的问题,而且什么BGX的也影响判断,只能用字符去比较。

这里我对矩阵里面的符号转换了一下,X转换为1,B转换为2,Y转换为4,G转换为6,我这里考虑的是叠加的G用另外两个数字相加,具体怎么区分可以看代码,在写这个文章的时候突然想到,用乘法会更好一点,也就是设置成1,2,3,6,有兴趣的可以试试,可以减少判断条件。

XBGBX
YBBYB
BGGXX
XYYBG
XYBGG
YYXYX

给他转换为:
1 2 6 2 1 
4 2 2 4 2 
2 6 6 1 1 
1 4 4 2
1 4 2 6 6 
4 4 1 4 1

这个运算一直不怎么顺畅,因为数字要斜着,所以我就先做了一个变化,就是把数组按照斜线给他立起来。就是数组顺时针转45°(看加粗的那些)

变成这样(看黑色加粗位置)

0 0 0 0 0 1 0 0 0 0 
0 0 0 0 4 0 2 0 0 0 
0 0 0 2 0 2 0 6 0 0 
0 0 1 0 6 0 2 0 2 0 
0 1 0 4 0 6 0 4 0 1 
4 0 4 0 4 0 1 0 2 0 
0 4 0 2 0 2 0 1 0 0 
0 0 1 0 6 0 6 0 0 0 
0 0 0 4 0 6 0 0 0 0 
0 0 0 0 1 0 0 0 0 0 
然后就是竖着的找2,6。横着的找4,6,中间考虑一下数据是否有断掉的,这个要让最终数据多加1.

代码如下:已AC全部。

import java.util.Scanner;
public class Main {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in); 
		int  n=sc.nextInt();
		int  m=sc.nextInt();
		String tem;
		tem = sc.nextLine();
		int  color[][] = new int [n][m];
			        for (int i = 0; i < n; i++) {//转换BYGX为1246
			            tem = sc.nextLine();
			            for (int j = 0; j < tem.length(); j++) {
			            	if(tem.charAt(j)=='B')
			            		color[i][j] = 2;
			            	if(tem.charAt(j)=='Y')
				                color[i][j] = 4;
			            	if(tem.charAt(j)=='G')
					            color[i][j] = 6;
			            	if(tem.charAt(j)=='X')
				                color[i][j] = 1;
			            }
			        } 
			        int [][] array= new int [m+n-1][m+n-1];
			        for(int i=0;i<n;i++)//数组给他立起来,顺时针转45°
			        	for(int j=0;j<m;j++)
			        		array[i+j][n-1-i+j]=color[i][j];
			       	int sum=0;
			       	int tag=0;
			       	for(int i=0;i<m+n-1;i++)
			       		{
			       		tag=0;
			       		for(int j=0;j<m+n-1;j++)//横着找
			       		
			       			{if(array[i][j]%4==2 && tag==0)
			       			{
			       				sum++;
			       				tag=1;
			       			}
			       			if(array[i][j]!=0&&array[i][j]%4!=2 && tag==1)//中间不连续情况
			       			{
			       				tag=0;
			       			}
			       			}
			       		}
			       	for(int i=0;i<m+n-1;i++)//竖着找
			       		{tag=0;
			       		for(int j=0;j<m+n-1;j++)
			       			{	
			       			if(array[j][i]/4==1 && tag==0)
			       		
			       			{
			       				sum++;
			       				tag=1;
			       			}
			       			if(array[j][i]!=0 && array[j][i]/4!=1&& tag==1)//中间不连续情况
			       			{
			       				tag=0;
			       			}
			       			}
			       		}
 System.out.println(sum);
}
}

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值