반응형
    
    
    
  https://www.acmicpc.net/problem/1400
1400번: 화물차
문제 화물차가 출발지 창고에서 짐을 싣고 배송지 창고까지 짐을 운반하려고 한다. 이 도시의 도로망을 나타낸 지도의 예는 다음과 같다. #A##0##1# .#..#..#. .#..#..#. .###2#.B. 도로망에서 차들은 동, ��
www.acmicpc.net
처음에는 시간이 필요할것 같은 문제여서 3차원 visitd르 접근하였다. 꾸역꾸역 문제를 풀엇지만 다른사람을 보고 생각지도 못햇던 방향으로 풀어서 적어보려고한다.
1. 3차원 배열을 만들 필요가없다.
이유 : 화물차가 기다리는 곳은 신호가 잇는곳 뿐이다. 따라서 신호앞에서 건너가지 못할겨우만 그 Queue는 그대로 다음 시간대에 보존시켜주면된다.
이렇게하면 최단 시가리 유지가 되는가??
이것도 visit 배열은 Queue의 매번 한사이클마다 돌게되면 시간의 증가함에따라 이동을 할 수있다.
그때 어던 교차로에서 기다렷다가 가는 상황에서 교차로가 이미 방문 햇다면 지금은 죽은 노드이기때문에 처내는게
가능하다.
package 삼성;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class 화물차 {
	// 01:20 ~
	static int dy[] = { 0, 0, 1, -1, 0 };
	static int dx[] = { 1, -1, 0, 0, 0 };
	static int N, M;
	static char[][] map;
	static boolean visit[][];
	static int cnt;
	static class Pair {
		int y;
		int x;
		public Pair(int y, int x) {
			super();
			this.y = y;
			this.x = x;
		}
	}
	// 최대 800초
	static int sy, sx;
	static int ey, ex;
	static class Signal {
		int dir;
		int a;
		int b;
		public Signal(int dir, int a, int b) {
			super();
			this.dir = dir;
			this.a = a;
			this.b = b;
		}
	}
	static Signal sig[];
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		StringTokenizer st;
		while (true) {
			st = new StringTokenizer(br.readLine());
			cnt = 0;
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			if (N == 0 && M == 0)
				break;
			map = new char[N][M];
			visit = new boolean[N][M];
			for (int i = 0; i < N; i++)
				map[i] = br.readLine().toCharArray();
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < M; j++) {
					if (map[i][j] >= '0' && map[i][j] <= '9') {
						cnt++;
					}
					if (map[i][j] == 'A') {
						sy = i;
						sx = j;
					}
					if (map[i][j] == 'B') {
						ey = i;
						ex = j;
					}
				}
			}
			// cnt 만큼 조사한다
			sig = new Signal[cnt];
			for (int i = 0; i < cnt; i++) {
				st = new StringTokenizer(br.readLine());
				int n = Integer.parseInt(st.nextToken());
				int d = st.nextToken().equals("-") ? 0 : 1;
				int a = Integer.parseInt(st.nextToken());
				int b = Integer.parseInt(st.nextToken());
				// d : 0 동서 , d : 1 남북
				sig[n] = new Signal(d, a, b);
			}
			br.readLine();
			// 답을 구한다.
			int ans = BFS();
			if (ans == -1) {
				sb.append("impossible\n");
			} else {
				sb.append(ans).append('\n');
			}
		}
		System.out.println(sb.toString());
	}
	public static int BFS() {
		int time = 0;
		Queue<Pair> q = new LinkedList<Pair>();
		q.add(new Pair(sy, sx));
		visit[sy][sx] = true;
		while (!q.isEmpty()) {
			int size = q.size();
			for (int s = 0; s < size; s++) {
				Pair cur = q.poll();
				if (cur.y == ey && cur.x == ex) {
					return time;
				}
				// 이동한다.
				for (int d = 0; d < 4; d++) {
					int ny = cur.y + dy[d];
					int nx = cur.x + dx[d];
					if (ny < 0 || nx < 0 || ny >= N || nx >= M)
						continue;
					if (visit[ny][nx])
						continue;
					if (map[ny][nx] == '.')
						continue;
					if (map[ny][nx] == '#' || map[ny][nx] == 'A' || map[ny][nx] == 'B') {
						visit[ny][nx] = true;
						q.add(new Pair(ny, nx));
					}
					if (map[ny][nx] >= '0' && map[ny][nx] <= '9' && d != 4) {
						int snum = map[ny][nx] - '0';
						if (checkSignal(snum, d, time)) {
							visit[ny][nx] = true;
							q.add(new Pair(ny, nx));
						}else {
							q.add(new Pair(cur.y,cur.x));
						}
					}
				}
			}
			time++;
		}
		return -1;
	}
	public static boolean checkSignal(int snum, int d, int time) {
		// dir ==0 동서 dir == 1 남북
		int dir = sig[snum].dir;
		int a = sig[snum].a;
		int b = sig[snum].b;
		int ans = 0;
		time = time % (a + b);
		// 동서가 먼저일때
		if (dir == 0) {
			if (time - a >= 0) {
				ans = (dir + 1) % 2;
			} else {
				ans = dir;
			}
		} else {
			if (time - b >= 0) {
				ans = (dir + 1) % 2;
			} else {
				ans = dir;
			}
		}
		// ans =0 동서 ans =1 남북
		// d 0
		if (ans == 0 && (d == 0 || d == 1))
			return true;
		if (ans == 1 && (d == 2 || d == 3))
			return true;
		return false;
	}
}
반응형
    
    
    
  'ProgramSoliving' 카테고리의 다른 글
| 백준 : 18808 스티커 붙이기 (0) | 2020.05.30 | 
|---|---|
| 백준 : 4889 안정적인 문자열 (0) | 2020.05.30 | 
| 백준 : 16929 (0) | 2020.05.26 | 
| 백준 : 8983 사냥꾼 (0) | 2020.05.24 | 
| 백준 : 관중석(10166) JAVA (0) | 2020.05.24 |