벽돌 을 치다
예시 1: 입력: grid = [1, 0, 0, 0], [1, 1, 1, 0] hits = [1, 0] 출력: [2] 설명: 우리 가 (1, 0) 위치의 벽돌 을 없 애 면 (1, 1) 과 (1, 2) 의 벽돌 이 떨어진다.그래서 우 리 는 2 로 돌아 가 야 한다.
예 2: 입력: grid = [1, 0, 0, 0], [1, 1, 0, 0] hits = [1, 1], [1, 0] 수출: [0, 0] 은 우리 가 (1, 0) 벽돌 을 없 앨 때 (1, 1) 벽돌 은 이미 지난 단계 에 없어 져 사 라 졌 다 고 설명 했다.그래서 매번 작업 을 없 앨 때마다 벽돌 이 떨 어 지지 않 습 니 다.벽돌 이 떨 어 진 벽돌 로 기억 되 지 않도록 주의 하 세 요.주의:
격자 의 줄 수 와 열의 범 위 는 [1, 200] 이다.제 거 된 숫자 는 격자 영역 을 초과 하지 않 습 니 다.매번 제거 가 다 르 고 그리드 내부 에 있 음 을 보증 할 수 있 습 니 다.제 거 된 위치 에 벽돌 이 없 을 수도 있 고, 이렇게 되면 벽돌 이 떨 어 지지 않 을 수도 있다.
해답: 두 드 리 기 전에 근처 의 칸 이 꼭대기 에 있 는 지, 꼭대기 에 있 으 면 떨 어 지지 않 고 떨 어 질 때 숫자 를 집계 하 는 방향 으로 생각 하고 있다.오래 걸 려 서 좀 부끄럽다
코드:
int[][] his;
int xLen;
int yLen;
public int[] hitBricks(int[][] grid, int[][] hits) {
int[] ans = new int[hits.length];
xLen = grid.length;
yLen = grid[0].length;
his = new int[xLen][yLen];
for (int i = 0; i < hits.length; i++) {
int x = hits[i][0];
int y = hits[i][1];
if (grid[x][y] == 0) {
ans[i] = 0;
continue;
}
grid[x][y] = 0;
ans[i] += hit(x, y - 1, grid, i + 1);
ans[i] += hit(x, y + 1, grid, i + 1);
ans[i] += hit(x - 1, y, grid, i + 1);
ans[i] += hit(x + 1, y, grid, i + 1);
}
return ans;
}
private int hit(int x, int y, int[][] grid, int hisV) {
if (x < 0 || x >= xLen || y < 0 || y >= yLen) {
return 0;
}
if (grid[x][y] == 0) {
return 0;
}
boolean kq = getKq(x, y, grid, hisV);
if (kq) {
return 0;
}
return remove(x, y, grid);
}
private int remove(int x, int y, int[][] grid) {
if (x < 0 || x >= xLen || y < 0 || y >= yLen) {
return 0;
}
if (grid[x][y] == 0) {
return 0;
}
grid[x][y] = 0;
int ans = 1;
ans += remove(x - 1, y, grid);
ans += remove(x + 1, y, grid);
ans += remove(x, y - 1, grid);
ans += remove(x, y + 1, grid);
return ans;
}
private boolean getKq(int x, int y, int[][] grid, int hisV) {
if (x == xLen || y == yLen || y < 0) {
return false;
}
if (grid[x][y] == 0) {
return false;
}
if (x == 0) {
return true;
}
if (his[x][y] == hisV) {
return true;
}
if (his[x][y] == 0 - hisV) {
return false;
}
// ,
his[x][y] = 0 - hisV;
if (getKq(x - 1, y, grid, hisV)) {
his[x][y] = hisV;
return true;
}
if (getKq(x + 1, y, grid, hisV)) {
his[x][y] = hisV;
return true;
}
if (getKq(x, y - 1, grid, hisV)) {
his[x][y] = hisV;
return true;
}
if (getKq(x, y + 1, grid, hisV)) {
his[x][y] = hisV;
return true;
}
return false;
}
거꾸로 생각: 지금 은 다 친 상태 입 니 다. 얼마나 많은 칸 이 남아 있 는 지 보고 표 시 를 합 니 다.반대로 두 드 린 칸 을 붙 이면 얼마나 붙 일 수 있 습 니까?코드:
public int[] hitBricks(int[][] grid, int[][] hits) {
int[] ans = new int[hits.length];
//
for (int i = 0; i < hits.length; i++) {
if (grid[hits[i][0]][hits[i][1]] == 1) {
grid[hits[i][0]][hits[i][1]] = -1;
}
}
for (int i = 0; i < grid[0].length; i++) {
if (grid[0][i] == 1) {
cleanToTwo(grid, 0, i);
}
}
for (int i = hits.length - 1; i >= 0; i--) {
//
if (grid[hits[i][0]][hits[i][1]] == -1 && nearTwo(grid, hits[i][0], hits[i][1])) {
ans[i] = cleanToTwo(grid, hits[i][0], hits[i][1]) - 1;
}
}
return ans;
}
// 2, , 1
private boolean nearTwo(int[][] grid, int x, int y) {
grid[x][y] = 1;
if (x == 0) {
return true;
}
if (x > 0 && grid[x - 1][y] == 2) {
return true;
}
if (x < grid.length - 1 && grid[x + 1][y] == 2) {
return true;
}
if (y > 0 && grid[x][y - 1] == 2) {
return true;
}
if (y < grid[0].length - 1 && grid[x][y + 1] == 2) {
return true;
}
return false;
}
// 2
private int cleanToTwo(int[][] grid, int x, int y) {
int ans = 1;
grid[x][y] = 2;
if (x > 0 && grid[x - 1][y] == 1) {
ans += cleanToTwo(grid, x - 1, y);
}
if (x < grid.length - 1 && grid[x + 1][y] == 1) {
ans += cleanToTwo(grid, x + 1, y);
}
if (y > 0 && grid[x][y - 1] == 1) {
ans += cleanToTwo(grid, x, y - 1);
}
if (y < grid[0].length - 1 && grid[x][y + 1] == 1) {
ans += cleanToTwo(grid, x, y + 1);
}
return ans;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Codility Lesson3】FrogJmpA small frog wants to get to the other side of the road. The frog is currently located at position X and wants to get to...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.