链接: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 6
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为1246tem = 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);
}
}