토마토_7576
2020. 2. 4. 14:06ㆍ카테고리 없음
시간초과가 나서 고심끝에 다른 이의 코드를 참조해,
arrayList -> Queue 로 바꿔줬더니 되었다.
그리고 더 간결한 코드를 위해
ripen_tomato.get(0)을 매번 호출하는 다음 코드는 안좋은 코드다.
public static void spread_rippen() {
for (; ptr > 0 ; ptr--) {
for (int i = 0; i < 4; i++) {
if(ripen_tomato.get(0).x+row[i] < 0 || ripen_tomato.get(0).y+col[i] <0
|| ripen_tomato.get(0).x+row[i] > a.length-1 || ripen_tomato.get(0).y+col[i]> a[0].length-1) continue;
if(a[ripen_tomato.get(0).x+row[i]][ripen_tomato.get(0).y+col[i]]==0) {
a[ripen_tomato.get(0).x+row[i]][ripen_tomato.get(0).y+col[i]]=1;
ripen_tomato.add(new Dot(ripen_tomato.get(0).x+row[i],ripen_tomato.get(0).y+col[i]));
}
}
ripen_tomato.remove(0); //삭제
}
}
다음 과같이 Dot dot 객체를 생성해서 ripen_tomato.get(0)은 한번만 호출하면 코드도 더 깔끔하고, 호출횟수도 줄어들것이다!
public static void spread_rippen() {
for (; ptr > 0 ; ptr--) {
Dot dot= ripen_tomato.get(0);
for (int i = 0; i < 4; i++) {
if(dot.x+row[i] < 0 || dot.y+col[i] <0
|| dot.x+row[i] > a.length-1 || dot.y+col[i]> a[0].length-1) continue;
if(a[dot.x+row[i]][dot.y+col[i]]==0) {
a[dot.x+row[i]][dot.y+col[i]]=1;
ripen_tomato.add(new Dot(dot.x+row[i],dot.y+col[i]));
}
}
ripen_tomato.remove(0); //삭제
}
}
같은 맥락으로
dot.x+row[i]를 int X =dot.x+row[i]로 하면 + 연산을 매번 안해도 된다.
dot.x+col[i]를 int X =dot.x+col[i]로 하면 + 연산을 매번 안해도 된다.
안좋은 코드
for (int i = 0; i < 4; i++) {
if(dot.x+row[i] < 0 || dot.y+col[i] <0
|| dot.x+row[i] > a.length-1 || dot.y+col[i]> a[0].length-1) continue;
if(a[dot.x+row[i]][dot.y+col[i]]==0) {
a[dot.x+row[i]][dot.y+col[i]]=1;
ripen_tomato.add(new Dot(dot.x+row[i],dot.y+col[i]));
}
}
개선된 코드
for (int i = 0; i < 4; i++) {
int X =dot.x+row[i];
int Y =dot.y+col[i];
if(X < 0 || Y <0 || X > a.length-1 || Y> a[0].length-1) continue;
if(a[X][Y]==0) {
a[X][Y]=1;
q.add(new Dot(X,Y));
}
}
내 코드
package study_IM;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
class Dot {
int x;
int y;
public Dot(int x,int y) { //생성자엔 void 안붙음
this.x=x;
this.y=y;
}
}
public class 토마토_7576 {
static int ptr=1;
static int a[][];
static int row[]= {0,-1,0,1};
static int col[]= {-1,0,1,0};
static int count;
public static void spread_rippen(Queue<Dot> q) {
for (ptr=q.size(); ptr > 0; ptr--) {
Dot dot=q.poll();
for (int i = 0; i < 4; i++) {
int X =dot.x+row[i];
int Y =dot.y+col[i];
if(X < 0 || Y <0 || X > a.length-1 || Y> a[0].length-1) continue;
// 범위 구할땐 if(0 <= X && X <a.length && 0 <= Y && Y < a[0].length ) continue; 가 더 직관적이다.
if(a[X][Y]==0) {
a[X][Y]=1;
q.add(new Dot(X,Y));
}
}
}// for ptr
}
public static void main(String[] args) throws IOException {
BufferedReader in =new BufferedReader(new InputStreamReader(System.in));
String read =in.readLine();
String arr[] =read.split(" ");
int N= Integer.parseInt(arr[0]);
int M= Integer.parseInt(arr[1]);
a =new int[M][N];
Queue<Dot> q=new LinkedList();
for (int i = 0; i < M; i++) {
String read1[] =in.readLine().split(" ");
for (int j = 0; j < N; j++) {
a[i][j]=Integer.parseInt(read1[j]);
if(a[i][j]==1) { //익은 토마토 기록
q.add(new Dot(i,j));
}
}
} //for n*m
ptr=q.size();
while(!q.isEmpty()) {
spread_rippen(q);
count++;
}
count--;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if(a[i][j]==0) { //안익은게 있다면
count=-1;
break;
}
}
if(count==-1) {
break;
}
} //for
System.out.println(count);
}// main
}
문제푸는데 4시간걸렸다.
1시간 풀기
2시간 디버깅 (bufferreader 찾아보기, 로직이 맞았는데 시간초과 남, max가 1칸 더 나옴 그래서 최종값에 -1 하려는데 로직 새로 짜느라 오래걸림 )
1시간 arrayList -> Queue 로 바꾸는 인사이트 얻음