반응형

1. 언어 : JAVA

 

2. 난이도 : Gold 4

15684번: 사다리 조작
 
www.acmicpc.net

3. 풀이

생각해보면 쉬운 문제다 2개의 함수의 구현이 필요하다.

DPS와 check 함수

dps 는 말그래도 depth 탐색 함수고

check는 사다리가 정답(1->1, 2->2, 3->3 .. N->N)인지 확인해주는 함수이다.

또한 map[][] 에 넣을때 오른쪽으로 갈수 있는 아이는 1, 왼쪽으로 갈수있는 아이는 -1로 저장하였다.

그리고 알아야 할 점은, 브루트포스이며 백트래킹을 사용한다.

소스코드는 다음과 같다.

 

4. 소스코드

import java.util.*;
import java.io.*;

public class Main {
	public static BufferedReader br = null;
	public static BufferedWriter bw = null;
	public static int N = 0;
	public static int M = 0;
	public static int H = 0;
	public static int result = 4;
	public static void main(String [] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		String [] input = br.readLine().split(" ");
		N = Integer.parseInt(input[0]);
		M = Integer.parseInt(input[1]);
		H = Integer.parseInt(input[2]);
		
		int [][] map = new int[H+2][N+1];
		
		for(int i=0; i<M; i++) {
			input = br.readLine().split(" ");
			int a = Integer.parseInt(input[0]);
			int b = Integer.parseInt(input[1]);
			map[a][b] = 1;
			map[a][b+1] = -1;
		}

		dfs(1, 1, map, 0);			
		
		if(result <= 3) {
			bw.write(result + "\n");
		}
		else {
			bw.write("-1");
		}
		bw.flush();
	}
	public static void dfs(int y, int x, int [][] map, int ladder) throws IOException {
		if(ladder > 3) {
			return;
		}
		
		if(check(map)) {
			result = Math.min(result, ladder);
		}
		
		for(int i=y; i<=H; i ++) {
			for(int j=1; j<=N-1; j ++) {
				if(map[i][j] == 0 && map[i][j+1] == 0) {
					map[i][j] = 1;
					map[i][j+1] = -1;
					dfs(i, j, map, ladder+1);
					map[i][j] = 0;
					map[i][j+1] = 0;
				}
			}
		}
	}
	public static int [][] copy(int [][] map) {
		int [][] copy = new int[H+2][N+1];
		for(int i=0; i<H+2; i++) {
			for(int j=0; j<N+1; j++) {
				copy[i][j] = map[i][j];
			}
		}
		return copy;
	}
	
	public static boolean check(int [][] map) throws IOException {
		int y = 0;
		int x = 0;
		for(int n=1; n<=N; n++) {
			y = 1;
			x = n;
			while(true) {
				if(map[y][x] == 1) {
					y ++;
					x ++;
				}
				else if (map[y][x] == -1) {
					y ++;
					x --;
				}
				else if(map[y][x] == 0) {
					y ++;
				}
				
				if(y == H+1) {
					if(x == n) {
						
					}
					else {
						return false;
					}
					break;
				}
			}
		}
		
		return true;
	}
}
반응형

'Algorithm > DFS' 카테고리의 다른 글

BOJ No.1043[거짓말]  (0) 2021.03.11
반응형

1. 언어 : JAVA

2. 난이도 : Gold 4

3. 풀이

벨만포드 알고리즘이다.

하지만 첫번째 풀이 할 때 벨만포드 알고리즘을 떠올리진 못하고, 단순히 최단거리라고해서 BFS로 해결하려고 했다.

그러니, 음수싸이클 때문에 무한루프가 돌면서 프로그램이 뻗는 현상이 발견 됐다.

그래서 방법을 찾다가 벨만 포드를 떠올렸다.

사실 인터넷쳐봤다.

아무튼,

That is not that big a deal !

휴..

벨만포드 알고리즘을 소개하려고한다.

조금이해하기 힘들었지만 간단하게 설명한다.

일단 반복문은 점의 갯수 - 1, 간선의 갯수 만큼 반복문을 진행해야한다.

점의갯수 - 1 만큼 진행하는 이유는 입력의 갯수가 1부터 차례대로 나온다는 보장이 없으니까 이다. ex) 5개의 점에서 4->5 로 가는 엣지가 먼저 입력으로 주어질 수도 있으니까.

그다음 간선의 갯수 만큼 반복문을 진행해야한다.

이 반복문을 진행할 때, 점화식은 다음과 같다.

        for(int i=1; i<N; i++) {
            for(int j=1; j<=M; j++) {
                if(dist[graph[j].start] != INF) {
                    dist[graph[j].end] = Math.min(dist[graph[j].end], dist[graph[j].start] + graph[j].weight);
                }
            }
        }

가고자하는 목적지의 값과, 현재 있는곳 + 다음으로 갈 weight의 값을 비교해서 작은 값을 넣어주는 점화식이다.

그림으로 차근차근 봐보자.

예를들어, 

4 4
1 2 4
2 3 5
3 4 -1
4 1 2

라는 입력이 있으면 그래프는 다음과 같다.

그러면 3x4의 반복문이 실행 될것이다.

그렇게 되면 dist는 어떻게 관리 되나 보자.

초기 dist는

0 INF INF INF 이렇게 되어있을 것이다.(우리가 초기화 해주어야함)

그다음

i가 처음 돌 때, 모든 간선을 돌면 이렇게 된다.

0 4 INF INF

0 4 9 INF

0 4 9 8

i가 두번째 세번째 돌때도 dist값은 변하지 않는다.

(아까 최악의 경우일 때 마지막까지 간다고 한 바 있다.)

이렇게 되면 음수여도 최단 경로를 찾을 수 있다!!

끝!!

That's NoNo... 안돼안돼

만약에 음수의 싸이클이 존재한다면?

5 5
1 2 2
2 3 2
3 4 -4
4 5 -5
5 3 -6

이런입력이 주어졌다고 치자.

그래프로 그리면 이런 형태가 나온다

직관적으로 봐도 저 3,4,5번이 싸이클로 보이쥬?

애초에 벨만포드에서 음수사이클이 발견됐다는건 휴지통으로 가져다가 버리면된다.

쓸모없는 입력이다.

즉, 음수 사이클이 발견 될 경우 우리의 정답은 보장 받지 못한다는 의미이다.

그래서 우리는 이 음수사이클이 발견이 안되면 정답을 찍어내고,

음수사이클이 발견된다면 그냥 -1을 출력하면 되는 것이다.

아니그래서 음수사이클은 어케하냐구요 현기증나요..

방법은 쉽다.

        boolean check = false;
        for(int i=1; i<=M; i++) {
            if(dist[graph[i].start] != INF && dist[graph[i].end] > dist[graph[i].start] + graph[i].weight) {
                check = true;
                break;
            }
        }

그냥 모든 간선을 돌면서, INF가 아니고, 만약 dist 값이 한번이라도 업데이트가 된다?

이건 그냥 쓰레기중에 쓰레기! 싸이클이 있다는 뜻이다.

이유는 직접해봐. 그림그리면서 표그리면서! 확인하면 직관적일꺼임

그래서 소스코드는 다음과 같다.

4. 소스코드

import java.util.*;
import java.io.*;

class q {
	int start;
	int end;
	int weight;
	
	public q(int start, int end, int weight) {
		this.start = start;
		this.end = end;
		this.weight = weight;
	}
}

public class Main {
	public static BufferedReader br = null;
	public static BufferedWriter bw = null;
	public static q [] graph = null;
	public static long [] dist = null;
	public static long INF = 987654321;

	public static void main(String [] args) throws IOException { 
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int N = Integer.parseInt(st.nextToken());
		int M = Integer.parseInt(st.nextToken());
		
		dist = new long[N + 1];
		graph = new q[M + 1];
		
		for(int i=1; i<=N; i++) {
			dist[i] = INF;
		}
		dist[1] = 0;
		
		for(int i=1; i<=M; i++) {
			String [] temp = br.readLine().split(" ");
			
			int a = Integer.parseInt(temp[0]);
			int b = Integer.parseInt(temp[1]);
			int c = Integer.parseInt(temp[2]);
			
			graph[i] = new q(a, b, c);
		}
		
        for(int i=1; i<N; i++) {
            for(int j=1; j<=M; j++) {
                if(dist[graph[j].start] != INF) {
                	dist[graph[j].end] = Math.min(dist[graph[j].end], dist[graph[j].start] + graph[j].weight);
                }
            }
        }
        
        boolean check = false;
        for(int i=1; i<=M; i++) {
            if(dist[graph[i].start] != INF && dist[graph[i].end] > dist[graph[i].start] + graph[i].weight) {
                check = true;
                break;
            }
        }
        
        if(check)
            System.out.println(-1);
        else {
            for(int i=2; i<=N; i++) {
                if(dist[i] == INF)
                    System.out.println("-1");
                else
                    System.out.println(dist[i]);
            }
        }
	}
}
반응형

'Algorithm' 카테고리의 다른 글

leetcode 173 java  (0) 2025.02.11
leetcode 701 java  (0) 2025.02.11
Programmers 완주하지 못한 선수  (0) 2022.01.29
BOJ No.1484[다이어트]  (0) 2021.03.23
BOJ No.1339[단어 수학]  (2) 2021.03.14
반응형

1. 언어 : JAVA

5427번: 불
 
www.acmicpc.net

 

 

2. 난이도 : Gold 4

 

3. 풀이

이 문제 역시 BFS이다.

 

아니 왜 그냥 골드4짜리에서 무작위로 고르는데 자꾸 BFS 문제가 나오는거지?

 

Anyway

 

이 문제는 BFS를 1개를 돌리면 되는 문제가 아니란걸 직감으로 느꼈다.

(사실 예전에 이런 비슷한 유형을 풀어본것 같기도?)

 

BFS문제는 설명하기가 힘든것 같다..

 

변수는 다음과 같다.

2차원 배열 check

2차원 배열 map

dequeSang // 상근이 큐

dequeFire // 불 큐

 

check는 상근이가 과거에 진입한 공간인지 아닌지 체크하는 곳

map은 벽과 불이 체크되어있는 곳.

 

BFS가 진행되면

1. Fire가 주위로 번지고(map에 표시)

2. 상근이가 있던곳 상하좌우 움직인다.

3-1. 만약 상근이가 움직이려고 하는 곳에 벽이나 Fire가 있으면 다음 단계 진행x

3-2. 만약 상근이가 움직이려고 하는 곳에 아무 장애물도 없으면 다음 단계 진행.

 

 

이렇게 하다보면 ,상근이가 벽쪽에 위치해 있을 때, 시간을 출력해주면된다.

 

설명보단 소스코드를 보면서 이해하는게 빠를 것같다.

 

혼자하면 이게문제야, 다른 코드도 보고싶은데 못봄.. 내가짠건 스파게티코드인데 흑흑 ㅜㅜ

 

 

4. 소스코드

import java.io.*;
import java.util.*;

class P {
	int y;
	int x;
	public P(int y, int x) {
		this.x = x;
		this.y = y;
	}
}
public class Main {
	public static int [] dx = {0, 0, -1, 1};
	public static int [] dy = {-1, 1, 0, 0};
	public static void main(String [] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
	
		int T = Integer.parseInt(br.readLine());
		String [][] map = null;
		int [][] check= null;
		Deque <P> dequeSang = null;
		Deque <P> dequeFire = null;
		int w = 0;
		int h = 0;
		
		for(int t=0; t<T; t++) {
			String [] temp = br.readLine().split(" ");
			w = Integer.parseInt(temp[0]);
			h = Integer.parseInt(temp[1]);
			map = new String[h][w];
			check = new int[h][w];
			dequeSang = new ArrayDeque<>();
			dequeFire = new ArrayDeque<>();
			
			int fireNum = 0;
			int sangNum = 0;
			
			for(int i=0; i<h; i++) {
				String s = br.readLine();
				for(int j=0; j<w; j++) {
					String st = s.substring(j, j+1);
					if(st.equals("@")) {
						check[i][j] = 1;
						sangNum ++;
						map[i][j] = ".";
						bw.flush();
						dequeSang.addLast(new P(i, j));
					}
					else if(st.equals("*")) {
						fireNum ++;
						dequeFire.addLast(new P(i, j));
						map[i][j] = st;
					}
					else {
						map[i][j] = st;
					}
				}
			}
			
			int fireNumTemp = 0;
			int sangNumTemp = 0;
			boolean find = false;
			int result = 0;
			int time = 0;
			
			while(!dequeFire.isEmpty() || !dequeSang.isEmpty()) {
				if(find) {
					break;
				}
				
				time ++;
				// fire Spread
				for(int i=0; i<fireNum; i++) {
					P pfire = dequeFire.pollFirst();
					int py = pfire.y;
					int px = pfire.x;
					for(int j=0; j<4; j++) {
						int ny = py + dy[j];
						int nx = px + dx[j];
												
						if(ny <= -1 || nx <= -1 || ny >= h || nx >= w) {
							continue;
						}
						
						if(map[ny][nx].equals("#") || map[ny][nx].equals("*")) {
							continue;
						}
						
						fireNumTemp ++;
						map[ny][nx] = "*";
						dequeFire.add(new P(ny, nx));
					}
				}
				fireNum = fireNumTemp;
				fireNumTemp = 0;
				
				for(int i=0; i<sangNum; i++) {
					P psang = dequeSang.pollFirst();
					int py = psang.y;
					int px = psang.x;
					
					for(int j=0; j<4; j++) {
						int ny = py + dy[j];
						int nx = px + dx[j];						
						
						if(ny <= -1 || nx <= -1 || ny >= h || nx >= w) {
							find = true;
							result = time;
							continue;
						}
						
						if(map[ny][nx].equals("*") || map[ny][nx].equals("#") || check[ny][nx] != 0) {
							continue;
						}

						sangNumTemp ++;
						check[ny][nx] = 1;
						dequeSang.addLast(new P(ny, nx));
					}
				}
				
				sangNum = sangNumTemp;
				sangNumTemp = 0;
			}
						
			if(result == 0)
				bw.write("IMPOSSIBLE\n");
			else
				bw.write(result + "\n");
			bw.flush();
		}
	}
}
반응형

'Algorithm > BFS' 카테고리의 다른 글

BOJ No.1261[알고스팟]  (0) 2021.03.12
BOJ No.12886[돌덩이]  (0) 2021.03.11
BOJ No.1005[AC Craft]  (0) 2021.03.11
반응형

1. 언어 : JAVA

1339번: 단어 수학
 
www.acmicpc.net

 

2. 난이도 : Gold 4

 

3. 풀이

이 문제 역시, 생각이 중요한 것 같다.

맨날 알고리즘도 제대로 구상안해놓고 코드먼저 짜려고하니,,

실수 나오고 시간도 오래걸리고 ㅋㅋ 

처음부터 제대로 된 알고리즘 안나오면 구현안해야겠다.

 

아무튼,

문제로 돌아와서

이러한 입력이 있다고 가정하자.

이러한 입력에서 각자리에 따른 Weight를 주는 것이다.

GCF -> G : 10^2, C : 10^1, F : ;10^0

ACDEB -> A : 10^4, C : 10^3, D : 10^2, E : 10^1, B : 10^0

이렇게 웨이트를 준 후, HashMap에 그 웨이트를 저장하는 것이다.

이게 무슨의미냐?

저장 후 해쉬맵에는 다음과 같이 있을 것이다.

왜냐하면 각자리를 보면서 이런식으로 해쉬값에 웨이트를 차곡차곡 저장 하기 때문이다.

이렇게 만들어진 해쉬맵을 List 에 담에서 정렬을 진행한다.(웨이트 값을기준으로

그러면 Comparator 클래스를 사용하여 웨이트 기준으로 정렬했음.) 그렇게 나온 정렬 된 값을 가지고 위에서부터 차례대로 9, 8, 7, 6, .... 을 결정할 수 있게 된다.

 

그렇게 되면

다음과 같은 형태로 정렬이 되고,

A는 9, C는 8 ... 의 값을 사용할 수 있게 된다.

이걸 사용하여, 문자를 숫자로 대체해준후, 모든 값을 더하면 결과 값이 나오게 된다.

개어렵네

 

4. 소스코드

import java.util.*;
import java.io.*;
class two {
	String alpa;
	int weight;
	public two(String alpa, int weight) {
		this.alpa = alpa;
		this.weight = weight;
	}
	
	public int getWeight() {
		return this.weight;
	}
}
public class Main {
	public static void main(String [] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		HashMap <String, Integer> hashMap = new HashMap();
		int N = Integer.parseInt(br.readLine());
		ArrayList <two> arrayList = new ArrayList();
		ArrayList <String> input = new ArrayList();
		for(int i=0; i<N; i++) {
			String temp = br.readLine();
			input.add(temp);
			int weight = 1;
			for(int j=temp.length()-1; j>=0; j--) {
				String s = temp.substring(j, j+1);
				if(hashMap.containsKey(s)) {
					hashMap.put(s, hashMap.get(s) + weight);
				}
				else {
					hashMap.put(s, weight);
				}
				weight *= 10;
			}
		}
		
		for(String key : hashMap.keySet()) {
			arrayList.add(new two(key, hashMap.get(key)));
		}
		
		Collections.sort(arrayList, new Comparator<two>() {
			@Override
			public int compare(two a, two b) {
				return b.getWeight() - a.getWeight();
			}
		});
		
		int value = 9;
		hashMap.clear();
		for(int i=0; i<arrayList.size(); i++) {
			two two = arrayList.get(i);
			hashMap.put(two.alpa, value);
			arrayList.set(i, new two(two.alpa, value--));
		}
		
		int result = 0;
		for(int i=0; i<input.size(); i++) {
			String t = input.get(i);
			for(int j=0; j<t.length(); j++) {
				String subStr = t.substring(j, j+1);
				t = t.replaceFirst(subStr, Integer.toString(hashMap.get(subStr)));
			}
			result += Integer.parseInt(t);
		}
		
		bw.write(result + "\n");
		bw.flush();
	}
}
반응형

'Algorithm' 카테고리의 다른 글

leetcode 173 java  (0) 2025.02.11
leetcode 701 java  (0) 2025.02.11
Programmers 완주하지 못한 선수  (0) 2022.01.29
BOJ No.1484[다이어트]  (0) 2021.03.23
BOJ No.11657[타임머신]  (0) 2021.03.20
반응형

1. 언어 : JAVA

1261번: 알고스팟
 
www.acmicpc.net

 
2. 난이도 : Gold 4

 

3. 풀이 

전형적인 BFS 문제이다. 

 

가장먼저

2차원 map

2차원 check(경로를 탐색 할 때의 메모이제이션 역할)

이 두가지면 충분하다.

 

2차원 배열 check 에는 이 배열까지 왔을 때, 몇개의 벽을 부셨을까이다.

 

즉,

 

4 4

0100

1000

0000

0000

 

이러한 입력이 주어졌다면,

(상우하좌 로 진행된다고 가정)

0111

1111

1111

1111

 

뭐 이런식으로 넣어질 것이다. 그래서!

다음 진행할 곳의 위치에서 벽을 사용한 값이 현재까지 벽 사용한 것의 + 1 보다 작거나 같으면 진행하지 않는다.

(이미 다른 녀석이 더 적은 벽을 뚫고 진행한 경험이 있기 때문에)

 
 
 
 

그리고 이렇게 벽이 있을때, 없을 때를 나눠서 queue에 넣어준다.

 

이렇게 진행하면 문제는 끝나게 된다.

 

하지만 이 문제를 해결하기 전에 처음에 메모리 초과 2번이나 났다.

왜냐하면, check 2차원 배열 안에 현재까지 깨뜨린 벽의 수를 넣은게 아니라 time기준으로 했기 때문이다.

아나 왜 time 기준으로했냐 똥멍청이냐

 

4. 소스코드

import java.util.*;
import java.io.*;

class p {
	int y;
	int x;
	int wall;
	public p(int y, int x, int wall) {
		this.y = y;
		this.x = x;
		this.wall = wall;
	}
}

public class Main {
	public static int [] dx = {0, 0, -1, 1};
	public static int [] dy = {-1, 1, 0, 0};
	public static BufferedReader br = null;
	public static BufferedWriter bw = null;
	public static void main(String [] args) throws IOException {
		int wallBreakNumber = 100001;
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));
		Deque <p> deque = new ArrayDeque<>();
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		int x = Integer.parseInt(st.nextToken());
		int y = Integer.parseInt(st.nextToken());
		
		int [][] map = new int[y][x];
		int [][] check = new int[y][x];
		
		for(int i=0; i<y; i++) {
			String s = br.readLine();
			for(int j=0; j<x; j++) {
				map[i][j] = Integer.parseInt(s.substring(j, j + 1));
				check[i][j] = 100001;
			}
		}
		
		// bfs
		check[0][0] = 0;
		deque.addLast(new p(0, 0, 0));
		while(!deque.isEmpty()) {
			p pair = deque.pollFirst();
			int px = pair.x;
			int py = pair.y;
			int pwall = pair.wall;
			
			if(py == y-1 && px == x-1) {
				wallBreakNumber = Math.min(pwall, wallBreakNumber);
			}
			
			for(int i=0; i<4; i++) {
				int nx = px + dx[i];
				int ny = py + dy[i];
								
				if(ny < 0 || ny >= y || nx < 0 || nx >= x) {
					continue;
				}
				
				if(check[ny][nx] <= pwall + 1) {
					continue;
				}
				
				if(map[ny][nx] == 1) {
					check[ny][nx] = pwall + 1;
					deque.addLast(new p(ny, nx, pwall + 1));
					continue;
				}
				
				if(map[ny][nx] == 0) {
					check[ny][nx] = pwall + 1;
					deque.addLast(new p(ny, nx, pwall));
					continue;
				}
			}
		}
		
		bw.write(wallBreakNumber + "\n");
		bw.flush();
		bw.close();
	}
}
반응형

'Algorithm > BFS' 카테고리의 다른 글

BOJ No.5427[불]  (0) 2021.03.14
BOJ No.12886[돌덩이]  (0) 2021.03.11
BOJ No.1005[AC Craft]  (0) 2021.03.11
반응형

1. 언어 : JAVA

 

1043번: 거짓말
 
www.acmicpc.net

 

2. 난이도 : Gold 4

 

3. 풀이

 

 

입력으로 다음과 같이 주어진다.

여기서 핵심은 문제를 이해하는 것이다. (맨날 덜렁대서 문제를 잘못이해해서 잘못풀었음..)

 

국어 먼저해야하나 하,,,

 

Anyway

 

문제를 이해했다고(?) 가정하고,

가장먼저 떠올라야 하는건 DFS로 파티에서 진실을 알고 있는 사람과 그 파티에 속한 사람 전부 DFS를 돌려주는것이다.

(왜냐하면 진실을 알고있는 자에게 과장할 수가 없으니까!)

 

이게 무슨소리냐?

 

위의 예를 보면 1번이 진실을 알고 있고,

파티는 총 5개 열린다.

파티1 -> 1번 참가

파티2 -> 2번 참가

파티3 -> 3번 참가

파티4 -> 4번 참가

파티5 -> 4, 1번 참가

무슨 파티에 인원이 1명이냐? 

 

이런식이다. 그러면 일단 파티1과 파티5에서는 허풍을 떨수가 없다.

그 다음 DFS를 돌려야하는데 파티1은 1번밖에 없으니 더이상 진행할 수 없고,

파티 5에서 4번이 다른파티에서 만약 참여했으면 그 파티에서도 과장을 할 수 없는 것이다.

 

따라서 4번이 있는 파티 4번에서도 과장 안된다.

 

따라서 파티2, 3에서만 과장을 할 수 있어서, 2가 답이다.

 

또 다른 예를 보면

 

진실 알고있는자 1

파티1 : 1,2

파티2 : 2,3

파티3 : 3,4,5

파티4 : 4, 6

파티5 : 5, 7

 

파티1번 시작 -> DFS(2번이 속한 파티도 안됨)

파티2번 시작 -> DFS(3번이 속한 파티도 안됨)

파티3번 시작 -> DFS(4번이 속한 파티도 안됨, 5번이 속한 파티도 안됨)

파티4, 파티5 <- 4번과 5번에 의해서 과장할 수 없음

 

이런식 인 것이다.

 

항상 알고리즘은 생각하기가 어렵지 생각하고 나면 구현은 딱히 어렵지 않다.

이번 문제 역시 현타왔다.

 

꾸준히 하다보면 늘것지뭐..

 

4. 소스코드

import java.util.*;
import java.io.*;
public class Main {
	public static BufferedReader br = null;
	public static BufferedWriter bw = null;
	public static int N = 0;
	public static int M = 0;
	public static void main(String [] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		
		int [] truePeople = new int[N];
		
		st = new StringTokenizer(br.readLine());
		int num = Integer.parseInt(st.nextToken());
		for(int i=0; i<num; i++) {
			truePeople[Integer.parseInt(st.nextToken()) - 1] = 1;
		}
		
		int [] check = new int[M];
		ArrayList <ArrayList <Integer>> party = new ArrayList();
		for(int i=0; i<M; i++) {
			party.add(new ArrayList<Integer>());
			st = new StringTokenizer(br.readLine());
			num = Integer.parseInt(st.nextToken());
			for(int j=0; j<num; j++) {
				int people = Integer.parseInt(st.nextToken()) - 1;
				party.get(i).add(people);
				if(truePeople[people] == 1) {
					check[i] = 1;
				}
			}
		}
		
		//풀이 시작
		for(int i=0; i<M; i++) {
			if(check[i] == 1) {
				check[i] = -1;
				dfs(check, party, i);
			}
		}
		int count = 0;
		if(num == 0) {
			for(int temp : truePeople) {
				if(temp == 1) count ++;
			}
		}
		else {
			for(int temp : check) {
				if(temp == 0) count ++;
			}
			
		}
		bw.write(count + "\n");
		bw.flush();
		bw.close();
		
	}
	public static void dfs(int [] check, ArrayList <ArrayList <Integer>> party, int presentLocation) {
		for(int i=0; i<party.get(presentLocation).size(); i++) {
			for(int j=0; j<party.size(); j++) {
				if(party.get(j).contains(party.get(presentLocation).get(i)) && check[j] != -1) { 
					check[j] = -1;
					dfs(check, party, j);
				}
			}
		}
	}
}
반응형

'Algorithm > DFS' 카테고리의 다른 글

BOJ No.15684[사다리 조작]  (0) 2021.03.23
반응형

1. 언어 : JAVA

12886번: 돌 그룹
 
www.acmicpc.net

2. 난이도 : Gold 5

 

3. 풀이

 

이 문제는 BFS 문제이다. 

그리고 3개의 돌이 주어지는데 메모이제이션으로 check[1501][1501][1501] 하면 메모리 초과가 난다.

그렇게이 첫번째, 두번째의 배열만 선언해줘도 충분하다.

(왜냐하면 처음, 두번째가 정해지면 3번째는 똑같이 오기 때문에)

 

그래서 check[1501][1501] 한개만 선언해줘도 충분하다.

 

그 다음은 문제에서 하라는대로하면된다.

 

1) 왼쪽 두개 비교 : 왼쪽이 더 클때

2) 왼쪽 두개 비교 : 오른쪽이 더 클때

3) 오른쪽 두개 비교 : 왼쪽이 더 클때

4) 오른쪽 두개 비교 : 오른쪽이 더 클때

(만약 이미 탐색한 경험이 있으면 진행하지 않는다.) 아래와 같이..

그리고 bfs함수 내에서 만약 모든 돌덩이가 같은 경우가 생기면 그 이후에 걸려있던 recursive는 다 제외 하도록함.

 

아마 메모리 초과와 처음에 어떤식으로 메모이제이션을 해야할지 감만 잡는다면 쉬운 문제인 것 같다.

 

 

 

4. 소스코드

import java.util.*;
import java.io.*;

public class Main {
	public static boolean b = false;
	public static BufferedReader br = null;
	public static BufferedWriter bw = null;
	public static boolean [][] check1 = null;
	public static boolean [][] check2 = null;
	public static void main(String [] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int [] rocks = new int[3];
		check1 = new boolean[1501][1501];
		check2 = new boolean[1501][1501];
		String [] temp = br.readLine().split(" ");
		
		rocks[0] = Integer.parseInt(temp[0]);
		rocks[1] = Integer.parseInt(temp[1]);
		rocks[2] = Integer.parseInt(temp[2]);
		
		bfs(rocks);
		
		if(b == true) {
			bw.write("1" + "\n");
		}
		else {
			if(rocks[0] == rocks[1] && rocks[1] == rocks[2]) {
				bw.write("1" + "\n");
			}
			else {
				bw.write("0" + "\n");
			}
		}
		
		bw.flush();
		bw.close();
	}
	
	public static void bfs(int [] rocks) throws IOException {
		if(b == true) {
			return;
		}
		
		if(check1[rocks[0]][rocks[1]] && check2[rocks[0]][rocks[1]]) {
			if(rocks[0] == rocks[1] && rocks[0]== rocks[2]) {
				b = true;
			}
			return;
		}
				
		// 왼쪽 2개비교
		// 왼쪽이 더 클때
		if(rocks[0] > rocks[1]) {
			int previousLeft = rocks[0];
			int previousRight = rocks[1];
			rocks[0] = previousLeft - previousRight;
			rocks[1] = previousRight + previousRight;	
			if(!check1[rocks[0]][rocks[1]]) {
				check1[rocks[0]][rocks[1]] = true;
				bfs(rocks);
			}
			rocks[0] = previousLeft;
			rocks[1] = previousRight;
		}
		// 오른쪽이 더 클 때
		if(rocks[0] < rocks[1]) {
			int previousLeft = rocks[0];
			int previousRight = rocks[1];
			rocks[0] = previousLeft + previousLeft;
			rocks[1] = previousRight - previousLeft;
			if(!check1[rocks[0]][rocks[1]]) {
				check1[rocks[0]][rocks[1]] = true;
				bfs(rocks);
			}
			rocks[0] = previousLeft;
			rocks[1] = previousRight;
		}
		
		// 오른쪽 2개 비교
		// 왼쪽이 더 클때
		if(rocks[1] > rocks[2]) {
			int previousLeft = rocks[1];
			int previousRight = rocks[2];
			rocks[1] = previousLeft - previousRight;
			rocks[2] = previousRight + previousRight;	
			if(!check2[rocks[1]][rocks[2]]) {
				check2[rocks[1]][rocks[2]] = true;
				bfs(rocks);
			}
			rocks[1] = previousLeft;
			rocks[2] = previousRight;
		}
		// 오른쪽이 더 클 때
		if(rocks[1] < rocks[2]) {
			int previousLeft = rocks[1];
			int previousRight = rocks[2];
			rocks[1] = previousLeft + previousLeft;
			rocks[2] = previousRight - previousLeft;	
			if(!check2[rocks[1]][rocks[2]]) {
				check2[rocks[1]][rocks[2]] = true;
				bfs(rocks);
			}
			rocks[1] = previousLeft;
			rocks[2] = previousRight;
		}
	}
	
	public static int [] copyArray(int [] a) {
		int [] copyArray = new int[3];
		for(int i = 0; i < a.length; i ++) {
			copyArray[i] = a[i];
		}
		return copyArray;
	}
}
반응형

'Algorithm > BFS' 카테고리의 다른 글

BOJ No.5427[불]  (0) 2021.03.14
BOJ No.1261[알고스팟]  (0) 2021.03.12
BOJ No.1005[AC Craft]  (0) 2021.03.11
반응형
  1. 언어 : JAVA,

  2. 난이도 : Gold 3

  3. 문제 : 

    1005번: ACM Craft
     
    www.acmicpc.net
  1. 풀이

입력 :

5 10

100000 99999 99997 99994 99990

4 5

3 5

3 4

2 5

2 4

2 3

1 5

1 4

1 3

1 2

4

 

1) 반대서 오는 방법

2) 출발지를 정해주는 방법

 

밑에 소스코드는 2번을 사용했다.

그래프를 그려보면 다음과 같다.

처음에 1부터 시작해서

의 점화식으로 진행하려고 했다.

 

여기 까지는 맞았다고 생각한다. 근데 첫 위치를 어디서 시작해야하는지 감이 안왔다.

입력이 이상하게 들어오는(?) 

예를들어

2 1

3 4

1 3

이런식으로 들어오고 위에서부터 진행하면 2->1 3->4 1->3 ? 서로 연결이 되지 않는다.

따라서, 2->1 1->3 3->4 이런식으로 진행을 해줘야한다.

 

그래서 Node[N] 의 배열을 선언해주고,

다음 차례에 있는 Node의 값을 +1 시켜준다.

Node

[1] [2] [3] [4]

 1   0  1   1

 

이런식으로 저장이 되고,

0인 것만 처음에 시작을 해주면된다.

 

처음에 2에서 시작을해서,

진행을 하면서, 다음 노드를 들어가기 전에

-1 해주고 node[i] 가 0 일 때

큐에 다시 넣어주면

3부터 다시 시작해줄 수 있게된다.

 

이렇게 되면 BFS 비슷한 코드를 짤 수 있게 된다.

 

Node 배열을 사용하지 않으면 반대서 거꾸로 오는 방법도 있으니 참고했으면 좋겠다.

 

 

  1. 소스코드
import java.util.*;
import java.io.*;

public class baekjoon_1005 {
	public static BufferedReader br = null;
	public static BufferedWriter bw = null;
	public static ArrayList <Integer> [] map = null;
	public static void main(String [] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		bw = new BufferedWriter(new OutputStreamWriter(System.out));

		int T = Integer.parseInt(br.readLine());
		
		for(int t = 0; t < T; t ++) {
			String [] temp = br.readLine().split(" ");
			int N = Integer.parseInt(temp[0]);
			int K = Integer.parseInt(temp[1]);
			
			int [] time = new int[N];
			int [] node = new int[N];
			int [] result = new int[N];
			
			temp = br.readLine().split(" ");
			ArrayList <Integer> [] map = new ArrayList[N];
			for(int j = 0; j < N; j ++) {
				time[j] = Integer.parseInt(temp[j]);
				map[j] = new ArrayList<>();
			}
			
			int s,e;
			for(int j = 0; j < K; j ++) {
				StringTokenizer st = new StringTokenizer(br.readLine());
				s = Integer.parseInt(st.nextToken());
				e = Integer.parseInt(st.nextToken());
				
				map[s-1].add(e - 1);
				node[e - 1] ++;
			}
			
            Queue<Integer> qu = new LinkedList<>();
            for(int i=0; i<N; i++) {
                if(node[i] == 0) {
                    result[i] = time[i];
                    qu.add(i);
                }
            }

            for(int i=0; i<N; i++) {
                int b = qu.poll();

                for(int index : map[b]) {
                    result[index] = Math.max(result[index], time[index] + result[b]);
                    if(--node[index] == 0){
                        qu.add(index);
                    }
                }
            }
			
			bw.write(result[Integer.parseInt(br.readLine())-1] + "\n");
		}
		bw.flush();
		bw.close();
	}
}
반응형

'Algorithm > BFS' 카테고리의 다른 글

BOJ No.5427[불]  (0) 2021.03.14
BOJ No.1261[알고스팟]  (0) 2021.03.12
BOJ No.12886[돌덩이]  (0) 2021.03.11

+ Recent posts