网易补招第1题解法
给定矩阵找出里面NETS的个数。
1. 每个字符在矩阵里必须是一个连通分量,每个元素与周围的八个元素相连。
2. 矩阵里'.'表示空白,'#'表示笔画。(之前写成‘*’表示笔画,实际上是'#')
3. 每个字符可能旋转90度,180度,270度。
下面是我的解法:
1. 给定元素坐标,若当前元素之前没有遍历过,则找出包含当前元素的连通分量。
2. 判断连通分量中元素的个数,然后再判断连通分量是否是4个字符中的一个。
3. 解法能保证判断连通分量是哪个字符的时候,传入的是这个字符最靠上然后最靠左的点的坐标。
#include <stdio.h> #include <stdlib.h> int nrow, ncol; char matrix[500][501]; # 用来表示输入矩阵 int step[8][2] = { # 用来遍历元素周围的八个元素 {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1} }; int cc(int i, int j) { // 计算包含元素i,j的连通分量包含的元素个数 int tmp, nr, nc, ret=1; if(matrix[i][j] != '#') return 0; matrix[i][j] = '*'; // 代表当前元素已遍历,'*'号用来判断连通分量代表的字符 for(tmp=0; tmp<8; tmp++) { nr = i+step[tmp][0]; nc = j+step[tmp][1]; if(nr>=0 && nr<nrow && nc>=0 && nc<ncol) ret += cc(nr, nc); } return ret; } int check_down(int i, int j) { // 从i,j开始,向下遍历有多少个连续的'*' int ret = 0; if(i<0 || j<0 || i>=nrow || j>= ncol) return 0; else while(i<nrow && matrix[i][j] == '*') { ret += 1; i +=1; } return ret; } int check_right(int i, int j) { // 从i,j开始,向右遍历有多少个连续的'*' int ret = 0; if(i<0 || j<0 || i>=nrow || j>= ncol) return 0; else while(j<ncol && matrix[i][j] == '*') { ret += 1; j +=1; } return ret; } int check_diag(int i, int j) { // 从i,j开始向右下遍历,有多少个连续的'*',用在判断N里 int ret = 0; if(i<0 || j<0 || i>=nrow || j>= ncol) return 0; else while(i<nrow && j<ncol && matrix[i][j] == '*') { ret += 1; i +=1; j +=1; } return ret; } int check_rdiag(int i, int j) { // 从i,j开始向左下遍历,有多少个连续的'*',用在判断N里 int ret = 0; if(i<0 || j<0 || i>=nrow || j>= ncol) return 0; else while(i<nrow && j>=0 && matrix[i][j] == '*') { ret += 1; i +=1; j -=1; } return ret; } int check_T(int i, int j) { // 判断连通分量是不是T int right=check_right(i, j), down=0; if(right==1) { down = check_down(i, j); if(down==7) { if (check_right(i+3, j)==5) // T顺时针转了270度 return 1; if(check_right(i+3, j-4)==5) // T顺时针转了90度 return 1; return 0; } else if(down==5) { return (check_right(i+4, j-3) == 7); // T顺时针转了180度 } else return 0; } else if(right == 7) { return (check_down(i, j+3)==5); // T没有转动 } else return 0; } int check_E(int i, int j) { // 判断是不是E int right = check_right(i, j), down; if(right==7) { down = check_down(i, j); if(down==1) { // E 顺时针转了180度 if(check_right(i+2, j)!=7) return 0; if(check_right(i+4, j)!=7) return 0; if(check_down(i, j+6)!=5) return 0; return 1; } else if(down==5) { // E 没有转动 if(check_right(i+2, j)!=7) return 0; if(check_right(i+4, j)!=7) return 0; return 1; } else return 0; } else if(right==5) { // E 顺时针转了90度 if(check_down(i, j)!=7) return 0; if(check_down(i, j+2)!=7) return 0; if(check_down(i, j+4)!=7) return 0; return 1; } else if(right==1) { // E 转了270度 if(check_down(i, j)!=7) return 0; if(check_down(i, j+2)!=7) return 0; if(check_down(i, j+4)!=7) return 0; if(check_right(i+6, j)!=5) return 0; return 1; } else return 0; } int check_S(int i, int j) { // 判断是不是S int right = check_right(i, j); if(right==7) { // S 没转,或者转了180度,两个图案一样 if(check_down(i, j)!=3) return 0; if(check_right(i+2, j)!=7) return 0; if(check_down(i+2, j+6)!=3) return 0; if(check_right(i+4, j)!=7) return 0; return 1; } else if(right==1) { // S转了90度或者270度 if(check_down(i, j)!=7) return 0; if(check_right(i+6, j)!=3) return 0; if(check_down(i, j+2)!=7) return 0; if(check_right(i, j+2)!=3) return 0; if(check_down(i, j+4)!=7) return 0; return 1; } else return 0; } int check_N(int i, int j) { // 判断是不是N int right=0, tmp; for(tmp=j; tmp<ncol && matrix[i][tmp] == '*'; tmp++) right +=1; if(right==2) { // N 没转或者转了180度 if(check_down(i, j) != 5) return 0; if(check_diag(i, j+1) != 5) return 0; if(check_down(i, j+6) != 5) return 0; return 1; } else if(right==5) { // N 转了90度或者270度。 if(check_rdiag(i+1, j+4)!=5) return 0; if(check_right(i+6, j)!=5) return 0; return 1; } else return 0; } int main() { int i, j, ret, N=0, T=0, E=0, S=0; scanf("%d %d", &nrow, &ncol); for(i=0; i<nrow; i++) scanf("%s", matrix[i]); for(i=0; i<nrow; i++) for(j=0; j<ncol; j++) { //printf("%d %d\n", i, j); ret = cc(i, j); if(ret==15) { // check if N N += check_N(i, j); } else if(ret == 11) { // check T T += check_T(i, j); } else if(ret == 23) { E += check_E(i, j); S += check_S(i, j); } } printf("N: %d\nT: %d\nE: %d\nS: %d\n", N, T, E, S); return 0; }