12919번: A와 B 2

수빈이는 A와 B로만 이루어진 영어 단어 존재한다는 사실에 놀랐다. 대표적인 예로 AB (Abdominal의 약자), BAA (양의 울음 소리), AA (용암의 종류), ABBA (스웨덴 팝 그룹)이 있다. 이런 사실에 놀란 수빈

www.acmicpc.net

 

 

 


 

 

  • 풀이

 

bfs 방식을 사용했습니다.

1. 큐에서 나온 문자열이 S와 같은 경우 : answer을 1로 초기화한 후 bfs 종료합니다.

2. 맨 앞에 B가 있는 경우 : 이전에 3번을 적용해서 B를 추가하고 뒤집었다는 뜻으로 반대로 맨 앞을 없애고 뒤집어서 큐에 넣어줍니다.

3. 맨 뒤에 A가 있는 경우 : 이전에 2번을 적용해서 A를 추가 했다는 소리이므로 A를 없애고 큐에 넣어줍니다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static int answer;

	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		String S = in.nextLine();
        String T = in.nextLine();
        Queue<String> queue = new LinkedList<>();
        answer = 0;
        
        queue.add(T);
        while (!queue.isEmpty()) {
            String temp = queue.poll();
            if(temp.equals(S))
            {
            	answer = 1;
                break;
            }
            if(temp.length() >= 2 &&temp.charAt(0) == 'B')
            {
                queue.add(new StringBuilder(temp.substring(1)).reverse().toString());
            }
            if(temp.length() >= 2 && temp.charAt(temp.length() - 1) == 'A')
            {
                queue.add(temp.substring(0,temp.length()-1));
            }
        }
		
	}
}

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

20207번: 달력

 수현이는 일년의 날짜가 1일부터 365일로 표시되어있는 달력을 가지고있다. 수현이는 너무나도 계획적인 사람이라 올 해 일정을 모두 계획해서 달력에 표시해놨다.  여름이 거의 끝나가자 장

www.acmicpc.net

 

 

 


 

 

 

  • 풀이

 

크기가 366까지 되있는 array 배열에 입력의 시작을 1, 끝을 -1로 초기화 시켜줍니다.

 

1. 반복문을 돌며 연결되어 있는 시작과 끝은 시작 인덱스만 초기화 시켜주며 최대 높이만 구해줍니다.

2. 끝이 발견되면 answer에 직사각형의 최대높이*길이를 통해 구해주고 변수를 0으로 초기화 시킵니다.

위의 작업을 1년인 365일의 +1일까지 작업해줍니다. 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static int answer;

	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

		answer = 0;
		int N = in.nextInt();
		int[] array = new int[367];
		for (int i = 0; i < N; i++) {
			array[in.nextInt()]++;
			array[in.nextInt()+ 1]--;
		}
		
		int start = 0;
		int height = 0;
		int connect = 0;
		for (int i = 0; i <= 366; i++) {
			connect += array[i];		// 연결이 더이상 안될 때 0이될 때를 체크해주기 위
			height = Math.max(height, connect);	// height
			
			if (start == 0 && connect != 0) {
				start = i;
			} else if (start != 0 && connect == 0) {
				answer += (i - start) * height;
				start = 0;
				height = 0;
			}
		}

	}
}

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

1706번: 크로스워드

동혁이는 크로스워드 퍼즐을 좋아한다. R×C 크기의 크로스워드 퍼즐을 생각해 보자. 이 퍼즐은 R×C 크기의 표로 이루어지는데, 퍼즐을 다 풀면 금지된 칸을 제외하고는 각 칸에 알파벳이 하나씩

www.acmicpc.net

 

 

 

 

 


 

 

 

  • 풀이

 

가로줄과 세로줄 별로 생성되는 String을 자료구조에 추가하여 정렬해주었습니다.

 

string에 뒤에 덧붙이는 작업이 많을 때 가변성이 있는 StringBuilder를 사용하여 시간을 조금 더 빠르게 작업할 수 있게 했습니다.

 

완성된 String들은 PriorityQueue에 추가하여 자동으로 오름차순으로 정렬시켜준 뒤 사전 순으로 가장 빠른 가장 앞에있는 queue의 데이터만 출력해주었습니다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static String answer;

	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

		int R = in.nextInt();
		int C = in.nextInt();
		char[][] array = new char[R][C];
		PriorityQueue<String> pq = new PriorityQueue<>();
		for(int i = 0; i < R; i++) {
			String s = in.nextLine();
			for(int j = 0; j < C ; j++)
				array[i][j] = s.charAt(j);
		}
		
		for(int i = 0; i < R; i++) {
			StringBuilder sb = new StringBuilder();
			for(int j = 0; j < C; j++) {
				if(array[i][j] == '#') {
					if(sb.length() > 1) {
						pq.add(sb.toString());
					}
					sb.setLength(0);
				} else {
					sb.append(array[i][j]);
					if(j == C-1) {
						if(sb.length() > 1) {
							pq.add(sb.toString());
						}
					}
				}
			}
		}
		
		for(int i = 0; i < C; i++) {
			StringBuilder sb = new StringBuilder();
			for(int j = 0; j < R; j++) {
				if(array[j][i] == '#') {
					if(sb.length() > 1) {
						pq.add(sb.toString());
					}
					sb.setLength(0);
				} else {
					sb.append(array[j][i]);
					if(j == R-1) {
						if(sb.length() > 1) {
							pq.add(sb.toString());
						}
					}
				}
			}
		}
		
		answer = pq.poll();
	}
}

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

11497번: 통나무 건너뛰기

남규는 통나무를 세워 놓고 건너뛰기를 좋아한다. 그래서 N개의 통나무를 원형으로 세워 놓고 뛰어놀려고 한다. 남규는 원형으로 인접한 옆 통나무로 건너뛰는데, 이때 각 인접한 통나무의 높이

www.acmicpc.net

 

 

 


 

 

  • 풀이

 

testcase만큼 작업을 하는데 크기가 N인 배열이 원으로 되어있을 때 인접한 값과의 차이의 최대값이 최소가 되는 값을 출력하면 되는 문제입니다.

 

문제는 그리디 방식으로 접근했습니다. 오름차순으로 정렬 후 해당 index 별로 index + 1은 왼쪽, index + 2 오른쪽으로 해준 뒤 차이 값 중 최대값을 초기화 시켜주는 방식으로 구현했습니다.

 

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static int N, M;
	static StringBuilder sb;
	static int[] array;

	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(sb);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

		int testcase = in.nextInt();
		sb = new StringBuilder();
		
		for(int i = 0; i < testcase; i++) {
			N = in.nextInt();
			array = new int[N];
			for(int j = 0; j < N; j++) {
				array[j] = in.nextInt();
			}
			Arrays.sort(array);
			
			int max = 0;
			for(int j = 0; j < N-2 ;j++) {
				max = Math.max(max, array[j+1] - array[j]);
				max = Math.max(max, array[j+2] - array[j]);
			}
			sb.append(max).append("\n");
		}
	}
}


class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

2636번: 치즈

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓

www.acmicpc.net

 

 

 

 


 

 

 

 

  • 풀이

 

시간 제한은 1초 입니다. 가로, 세로 최대값이 100인 것을 감안해서 보면 빡빡하지 않은 시간으로 문제설명대로 구현하면 된다고 생각했습니다.

 

문제의 구현 방법은 bfs방식을 사용했습니다.

  1. bfs를 통해 (0, 0)에서 0을 타고다니며 0과 인접한 1만 melt라는 queue에 추가시켜주었습니다. (같은 index가 추가되지 않게 배열 하나를 추가로 만들어 중첩을 방지해 주었습니다.)
  2. 현재가 마지막 치즈를 녹이는 작업이 될 수 있으므로 size라는 변수를 만들어 melt의 size로 초기화 시켜주었습니다. (만약, melt의 size가 0일경우 초기화 시켜주기 전 반복문을 종료합니다.)
  3. 위의 bfs가 종료되면 melt에는 현재 시간에 녹을 치즈의 index만 남아있습니다. melt 큐에 저장된 모든 위치의 치즈인 1을 0으로 바꾸는 작업을 합니다.
  4. count변수를 만들어 횟수를 1 증가시켜줍니다.
  5. 위의 1~4 작업을 반복합니다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
    static int N, M;
    static StringBuilder sb;
    static int[][] array;
    static int[] dx = {-1,1,0,0};
    static int[] dy = {0,0,-1,1};
    static boolean[][] check;
    
	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(sb);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextInt();
		M = in.nextInt();
		array = new int[N][M];
		check = new boolean[N][M];
		sb = new StringBuilder();
		
		for(int i = 0; i < N; i++) {
			for(int j = 0; j < M; j++) {
				array[i][j] = in.nextInt();
	
			}
		}
		
		bfs();
	}
	
	private static void bfs() {
		Queue<Node> queue = new LinkedList<>();
		Queue<Node> melt = new LinkedList<>();
		boolean[][] visit = new boolean[N][M];
		int a = 0, b = 0, count = 0, size = 0;
		
		while(true) {
			for(int i = 0; i < N; i++)
				Arrays.fill(check[i], false);
			queue.add(new Node(0, 0));
			check[0][0] = true;
			while(!queue.isEmpty()) {
				Node node = queue.poll();
				
				for(int direction = 0; direction < 4; direction++) {
					int r = node.x + dx[direction];
					int c = node.y + dy[direction];
					
					if(r < 0 || c < 0 || r >= N || c >= M) continue;
					if(check[r][c]) continue;
					if(array[r][c] == 1) {
						if(!visit[r][c]) {
							visit[r][c] = true;
							melt.add(new Node(r,c));
						}
						continue;
					}
					
					queue.add(new Node(r, c));
					check[r][c] = true;
				}
			}
			if(melt.size() == 0) break;
			
			size = melt.size();
			while(!melt.isEmpty()) {
				Node node = melt.poll();
				array[node.x][node.y] = 0;
			}
			
			count++;
		}
		sb.append(count).append("\n").append(size);
	}
}

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

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

3197번: 백조의 호수

입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500. 다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.

www.acmicpc.net

 

 

 

 


 

 

 

  • 풀이

 

bfs를 사용해서 문제를 해결했습니다.

 

처음에 빙하를 녹이는 과정에서 (0,0)~(R-1,C-1)까지 반복문을 돌며 빙하를 녹이는 코드를 작성하니 시간초과가 발생했습니다.

 

시간을 줄이기위해 다음에 녹을 빙하를 queue에 저장하여 녹여주었습니다. 해당 작업으로도 시간초과가 발생하여 첫번째 'L'이 두번째 'L'로 가는 과정에서의 X를 모두 queue에저장하여 다음 빙하를 녹인 뒤엔 queue에 저장되어있는 X부터 다시 탐색하니 시간초과는 해결되었습니다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static int R, C, answer;
	static char[][] array;
	static Node one, two;
	static boolean[][] check;
	static Queue<Node> water, queue;
	static int[] dx = {0,0,-1,1};
	static int[] dy = {-1,1,0,0};
	
	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		R = in.nextInt();
		C = in.nextInt();
		answer = 0;
		array = new char[R][C];
		check = new boolean[R][C];
		water = new LinkedList<>();
		queue = new LinkedList<>();
		
		for(int i = 0; i < R; i++) {
			String s = in.nextLine();
			for(int j = 0; j < C; j++) {
				array[i][j] = s.charAt(j);
				if(array[i][j] == 'L') {
					if(one == null)
						one = new Node(i, j);
					else
						two = new Node(i, j);
				}
				if(array[i][j] != 'X') {
					water.add(new Node(i, j));
				}
			}
		}
		queue.add(one);
		check[one.x][one.y] = true;
		while(bfs()) {
			Melt();
			answer++;
		}
	}
	
	private static void Melt() {
		int size = water.size();
		
		for(int i = 0 ; i < size ; i++) {
			Node now = water.poll();
			
			for(int direction = 0 ; direction < 4 ; direction++) {
				int r = now.x + dx[direction];
				int c = now.y + dy[direction];
				
				if(r < 0 || r >= R || c < 0 || c >= C) continue;
				if(array[r][c] != 'X') continue;
				
				array[r][c] = '.';
				water.add(new Node(r, c));
				
			}
		}
	}
	
	private static boolean bfs() {
		Queue<Node> temp = new LinkedList<>();
		
		while(!queue.isEmpty()) {
			Node node = queue.poll();
			if(node.x == two.x && node.y == two.y) return false;
			
			for(int direction = 0; direction < 4; direction++) {
				int r = node.x + dx[direction];
				int c = node.y + dy[direction];
				
				if(r < 0 || r >= R || c < 0 || c >= C) continue;
				if(check[r][c]) continue;
				check[r][c] = true;
				if(array[r][c] == 'X') {
					temp.add(new Node(r, c));
					continue;
				}
				
				queue.add(new Node(r, c));
			}
		}
		queue = temp;
		return true;
	}
}

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

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

10159번: 저울

첫 줄에는 물건의 개수 N 이 주어지고, 둘째 줄에는 미리 측정된 물건 쌍의 개수 M이 주어진다. 단, 5 ≤ N ≤ 100 이고, 0 ≤ M ≤ 2,000이다. 다음 M개의 줄에 미리 측정된 비교 결과가 한 줄에 하나씩

www.acmicpc.net

 

 

 

 


 

 

 

  • 풀이

 

자신보다 집적접으로 무게가 낮거나 높은 물건을 통해 간접적으로 낮거나 높은 물건을 모두 찾는 문제입니다.

 

이를 풀기 위한 알고리즘은 모든 정점에서 모든 정점의 최단거리를 구하는 플로이드 와샬을 이용했습니다. 플로이드 와샬은 O(N^3)의 시간복잡도를 가지기 때문에 시간을 잘 고려해야합니다. 현재 문제의 N의 최대값은 100으로 100^3은 1000000으로 1초안에 들어오기에 충분한 연산횟수입니다. (참고로 1초에 1억번 정도의 연산을 한다고 생각하시면 됩니다.)

 

해당 문제를 풀기 위해선 자신보다 무게가 많이 나가는 물건과 무게가 적게 나가는 물건을 구별해야합니다. 이유는 예시를 들어보면 1번의 무게보다 낮은 2번과 2번의 무게보다 낮은 3번이 있다고 가정하면 1>2>3>이 될 것 입니다. 하지만 1번의 무게보다 낮은 2번과 2번의 무게보다 높은 3번이 있다고 가정하면 1>2<3 ???? 이 될 것입니다. 그렇기 때문에 본인보다 무게가 높은 것과 무게가 낮은 것을 구별해야합니다.

 

저의 경우에는 a > b의 경우 array[a][b] = 1, array[b][a] = -1로 초기화 하였습니다.

 

이제 플로이드 와샬 알고리즘을 통해, array[i][k]가 0이 아닌 가정하에 array[i][k] == array[k][j]이라면 array[i][j] = array[i][k]로 초기화하며 자신보다 무게가 낮거나 높은 물건을 확인해주었습니다. 즉, i보다 k가 높으면서 k보다 j가 높다면 i보다 j도 높다는 뜻의 알고리즘입니다. (낮은 방식도 마찬가지)

 

위의 플로이드 와샬 알고리즘이 종료가 되면 현재 무게보다 높거나 낮은 모든 물건을 구해줄 수 있을 것 입니다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static int N, M;
	static StringBuilder sb;	
	static int[][] array;
	
	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(sb);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextInt();
		M = in.nextInt();
		sb = new StringBuilder();
		array = new int[N+1][N+1];
		
		for(int i = 0; i < M; i++) {
			int a = in.nextInt();
			int b = in.nextInt();
			
			array[a][b] = 1;
			array[b][a] = -1;
		}
		
		for(int k = 1; k <= N; k++) {
			for(int i = 1; i <= N; i++) {
				for(int j =1; j <= N; j++) {
					if (array[i][k] != 0 && array[i][k] == array[k][j]) {
                        array[i][j] = array[i][k];
                    }
				}
			}
		}
		
		for(int i = 1; i <= N; i++) {
			int count = 0;
			for(int j =1; j <= N; j++) {
				if(i == j) continue;
				if(array[i][j] != 0) continue;
				
				count++;
			}
			sb.append(count).append("\n");
		}
	}
}

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

 

1351번: 무한 수열

첫째 줄에 3개의 정수 N, P, Q가 주어진다.

www.acmicpc.net

 

 

 


 

 

 

  • 풀이

 

처음엔 재귀형식으로 풀어보려했지만 시간초과가 떴습니다. 

 

다음 dp를 통해 풀어보려 했지만 N의 최대값이 너무 크기때문에 배열을 만들 수 없었습니다. 그래서 Map을 통해 dp배열처럼 사용했습니다. 

 

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

public class Main {
	static long N, answer;
	static int P, Q;
	static Map<Long, Long> map;
	
	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(answer);
	}

	// 데이터
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextLong();
		P = in.nextInt();
		Q = in.nextInt();
		answer = 0;
		map = new HashMap<>();
		
		answer = recursion(N);
	}
	
	private static long recursion(long value) {
		if(value == 0) return 1;
		if(map.containsKey(value)) return map.get(value);
		
		map.put(value, recursion(value/P) + recursion(value/Q));
		return map.get(value);
	}
}

class InputReader {
	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

	public InputReader(InputStream st) {
		this.stream = st;
	}

	public int read() {
		if (snumChars == -1)
			throw new InputMismatchException();
		if (curChar >= snumChars) {
			curChar = 0;
			try {
				snumChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (snumChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public int[] nextIntArray(int n) {
		int a[] = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt();
		}
		return a;
	}

	public String nextLine() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
}

+ Recent posts