알고리즘/문제풀이

[시뮬레이션] 로봇청소기

lipnus 2019. 3. 31. 00:45
반응형

백준 14503번 로봇청소기 (삼성 SW역량테스트 기출)

https://www.acmicpc.net/problem/14503


import javax.swing.text.Position;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

static int N;
static int M;
static int dir;
static int[][] map;
static int cleanCount =0;

static int[] rotate = {3, 2, 1, 0};

public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());

N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[N+1][M+1];

st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
Position startPos = new Position(n+1, m+1);
dir = Integer.parseInt(st.nextToken());


//지도
for(int i=1; i<=N; i++){
st = new StringTokenizer(br.readLine());
for(int j=1; j<=M; j++){
map[i][j] = Integer.parseInt(st.nextToken());
}
}

loop(startPos);

System.out.println(cleanCount);


}


static void loop(Position start){

Position now = start;
cleanCount++;
map[start.n][start.m] =2;

while (true){

//왼쪽부터 4방향 탐색
boolean isMoved = false;
for(int i=0; i<4; i++){

rotateDir();
Position next = getNext(now);

if(isCanGo(next) && !isCleaned(next)){

map[next.n][next.m] = 2;
cleanCount++;

now = next;
isMoved=true;
break;
}


}

//움직이지 못했으면 후진
if(isMoved==false){
Position next = getBack(now);

if(isCanGo(next)){
now = next;
}else{ //후진불가능
break;
}
}
}
}

static void print(){
for(int i=1; i<=N; i++){
for(int j=1; j<=M; j++){
}
System.out.println();
}
}


//왼쪽으로 90도 회전
static void rotateDir(){
if(dir==0) dir=3;
else if(dir==1) dir=0;
else if(dir==2) dir=1;
else if(dir==3) dir=2;
}

/**
* 현재위치와 방향에서 이동해야 할 위치를 반환
* @param now
* @return
*/
static Position getNext(Position now){

if(dir==0) return new Position(now.n-1, now.m);
if(dir==1) return new Position(now.n, now.m+1);
if(dir==2) return new Position(now.n+1, now.m);
return new Position(now.n, now.m-1);
}


/**
* 현재위치에서 후진했을때의 위치를 리턴
* @param now
* @return
*/
static Position getBack(Position now){

if(dir==0) return new Position(now.n+1, now.m);
if(dir==1) return new Position(now.n, now.m-1);
if(dir==2) return new Position(now.n-1, now.m);
return new Position(now.n, now.m+1);
}


//갈 수 있는 곳인지 리턴
static boolean isCanGo(Position next){

//벽인가
if(map[next.n][next.m]==1) return false;

return true;
}


//청소를 했는지 여부를 리턴
static boolean isCleaned(Position next){
if(map[next.n][next.m] == 2) return true;
return false;
}





static class Position{
int n;
int m;

Position(int n, int m){
this.n = n;
this.m = m;
}
}
}

딴거에 비해 이문제가 정답률이 높은건..

기본구현이 까다로워 사람들이 테스트케이스도 통과못해서 제출을 안내서 그런 것 같다.

테스트케이스만 맞추면 예외는 거의 생기지 않는 듯.



틀렸던 부분1

//왼쪽으로 90도 회전
static void rotateDir(){
if(dir==0) dir=3;
if(dir==1) dir=0;
if(dir==2) dir=1;
if(dir==3) dir=2;
}

처음에 이렇게 해놨었다. 이러면 if가 여러번 걸릴수도 있다.


//왼쪽으로 90도 회전
static void rotateDir(){
if(dir==0) dir=3;
else if(dir==1) dir=0;
else if(dir==2) dir=1;
else if(dir==3) dir=2;
}




틀렸던 부분2

Position startPos = new Position(n, m);

Position startPos = new Position(n+1, m+1);


이건 실제 상황이었으면 스스로 찾기 힘들었을 것 같다.


맵의 바깥쪽은 무조건 벽으로 둘러쌓여있고, 그 벽은 좌표로 안친다.

내가 (2,2)로 생각했던 곳이 이 문제에서는 (1,1)이다. 시바..

반응형