5557번: 1학년

상근이가 1학년 때, 덧셈, 뺄셈을 매우 좋아했다. 상근이는 숫자가 줄 지어있는 것을 보기만 하면, 마지막 두 숫자 사이에 '='을 넣고, 나머지 숫자 사이에는 '+' 또는 '-'를 넣어 등식을 만들며 놀

www.acmicpc.net

 


 

  • 생각

다시 풀어보려했는데 실패했다.. 다른 사람이 정리해 놓은 걸로 이해하였다.

 

상근이는 덧셈, 뺄셈을 통해 줄 지어진 숫자를 연산하여 가장 마지막 숫자가 나오도록 하고자 한다.

그러나, 연산 도중에 나올 수 있는 숫자는 0이상 20이하라고 한다.

 

 여기서 크기가 21인 배열을 생각할 수 있다.

 

 

예시인 "8 3 2 4 8 7 2 4 0 8 8" 을 생각해보자.

 

처음 8이 올 때, 8이 될 수 있는 경우의 수는 1이다.

 

 

8 다음 3이 올 때, 3에서 할 수 있는 연산은 +3, -3 이다.

 

 

그 다음 2가 올 때 할 수 있는 연산은 +2, -2 이다.

 

 

4가 올 때 할 수 있는 연산은 +4, -4 로 범위를 넘어가면 빼주면 된다.

 

 

[BOJ] 백준 5557 - 1학년

백준 5557 - 1학년 상근이는 덧셈, 뺄셈을 통해 줄 지어진 숫자를 연산하여 가장 마지막 숫자가 나오도록 하고자 한다. 그러나, 연산 도중에 나올 수 있는 숫자는 0이상 20이하라고 한다.  여기서

hyunah030.tistory.com

 

  • 코드

정답 코드 : dp[i][j] = j번 계산했을때 숫자 i값이 나올 수 있는 경우의 수로 N-1번 돌렸을 때 dp[array[N - 1]][N - 2]의 값을 얻어온다.

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int N;
	static long[][] dp;
	static int[] array;

    public static void main(String[] args) throws Exception {
        SetData();
        System.out.println(dp[N-2][array[N-1]]);
    }
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);

        N = in.nextInt();
        
        dp = new long[N][21];
        array = new int[N];
        
        for(int i = 0; i < N; i++) {
            array[i]=  in.nextInt();
        }
        dp[0][array[0]]=1;
        
        for(int i = 1; i < N; i++) {
            for(int j = 0; j <= 20; j++) {
                if(dp[i-1][j] != 0) {
                    if(j+array[i] <= 20) {
                        dp[i][j+array[i]] += dp[i-1][j];
                    }
                    if(j-array[i] >= 0) {
                        dp[i][j-array[i]] += dp[i-1][j];
                    }
                }
            }
        }
	}
}
	

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;
	}
}

 

1027번: 고층 건물

세준시에는 고층 빌딩이 많다. 세준시의 서민 김지민은 가장 많은 고층 빌딩이 보이는 고층 빌딩을 찾으려고 한다. 빌딩은 총 N개가 있는데, 빌딩은 선분으로 나타낸다. i번째 빌딩 (1부터 시작)

www.acmicpc.net


 

  • 생각

기울기를 통해서 볼 수 있는 건물의 수를 파악한다. 가장 많이 보이는 건물의 최대값을 유지시켜줌.

애먹었던 부분은 자료형 때문이였는데, angle의 값을 99999999999로 주니까 long 범위를 벗어나버려서 되지 않았다. TIP) 이때 숫자 맨뒤에 l or L을 붙여주면 가능해짐

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int answer, number;
	static long[] array;

	public static void main(String[] args) throws Exception {
		SetData();
		Calculate();
		System.out.println(answer);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		number = in.nextInt();
		array = new long[number+1];
		answer = 0;
		
		for(int index = 1; index <= number; index++)
			array[index] = in.nextLong();
		
	}
	
	private static void Calculate() {
		for(int i = 1;i <= number;i++){
			int temp=0;
			
			double angle = 99999999999L;
			for(int j = i-1;j >= 1;j--){
				double lean=(double)(array[j]-array[i])/(double)(j-i);
				if(lean<angle){
					temp++;
					angle=lean;
				}
			}
			
			angle = -99999999999L;
			for(int j = i+1;j <= number;j++){
				double lean=(double)(array[j]-array[i])/(double)(j-i);			
				if(lean>angle){
					temp++;
					angle=lean;
				}
			}
			
			answer=Math.max(answer,temp);
		}
	}
}
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;
	}
}

 

 

1012번: 유기농 배추

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 

www.acmicpc.net

 


 

  • 생각

bfs의 전형적인 문제인 것 같다.

반복문을 돌면서 1을 만나면 상, 하, 좌, 우의 값이 1인 index를 check해주면서 bfs를 돌렸다. check가 되지않았던 1을 처음 봤을 땐 count를 1씩 증가시켜 주면서 필요한 배추흰지렁이의 수를 맞춰주었다.

 

 

  • 코드

정답 코드 : 1을 발견할때마다 bfs로가서 인접한 1을 check해주며 돔.

 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	static int[][] array;
	static boolean[][] check;
	static int[] x = { -1, 1, 0, 0 };
	static int[] y = { 0, 0, -1, 1 };
	static int M;
	static int N;

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

		int testCase = Integer.parseInt(br.readLine());
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < testCase; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			M = Integer.parseInt(st.nextToken());
			N = Integer.parseInt(st.nextToken());
			int K = Integer.parseInt(st.nextToken());
			array = new int[M][N];
			check = new boolean[M][N];
			for (int j = 0; j < K; j++) {
				st = new StringTokenizer(br.readLine());
				int x = Integer.parseInt(st.nextToken());
				int y = Integer.parseInt(st.nextToken());
				array[x][y] = 1;
			}

			int count = 0;
			for (int a = 0; a < M; a++) {
				for (int b = 0; b < N; b++) {
					if (!check[a][b] && array[a][b] == 1) {
						count++;
						check[a][b] = true;
						bfs(a, b);
					}
				}
			}
			
			sb.append(count + "\n");
		}
		
		System.out.print(sb);
	}

	private static void bfs(int a, int b) {
		Queue<int[]> queue = new LinkedList<>();
		queue.offer(new int[] { a, b });

		while (!queue.isEmpty()) {
			int location[] = queue.poll();

			for (int direction = 0; direction < 4; direction++) {
				int r = location[0] + x[direction];
				int c = location[1] + y[direction];

				if (r >= 0 && c >= 0 && r < M && c < N) {
					if (array[r][c] == 1 && !check[r][c]) {
						queue.offer(new int[] { r, c });
						check[r][c] = true;
					}
				}
			}
		}
	}

}

 

 

정답 코드 : 3달 뒤 코드이다. stream으로 수를 받아왔다.

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int M, N;
	static int[] x = { -1, 1, 0, 0 };
	static int[] y = { 0, 0, -1, 1 };
	static int[][] array;
	static boolean[][] check;
	static StringBuilder sb;

	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);
		
		sb = new StringBuilder();
		int testCase = in.nextInt();

		for (int i = 0; i < testCase; i++) {
			M = in.nextInt();
			N = in.nextInt();
			int K = in.nextInt();
			array = new int[M][N];
			check = new boolean[M][N];
			
			for (int j = 0; j < K; j++) {
				array[in.nextInt()][in.nextInt()] = 1;
			}

			int count = 0;
			for (int a = 0; a < M; a++) {
				for (int b = 0; b < N; b++) {
					if (!check[a][b] && array[a][b] == 1) {
						count++;
						check[a][b] = true;
						bfs(a, b);
					}
				}
			}
			
			sb.append(count + "\n");
		}
	}
	
	private static void bfs(int a, int b) {
		Queue<int[]> queue = new LinkedList<>();
		queue.offer(new int[] { a, b });

		while (!queue.isEmpty()) {
			int location[] = queue.poll();

			for (int direction = 0; direction < 4; direction++) {
				int r = location[0] + x[direction];
				int c = location[1] + y[direction];

				if (r >= 0 && c >= 0 && r < M && c < N) {
					if (array[r][c] == 1 && !check[r][c]) {
						queue.offer(new int[] { r, c });
						check[r][c] = true;
					}
				}
			}
		}
	}
}
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;
	}
}

 

 

2579번: 계단 오르기

계단 오르기 게임은 계단 아래 시작점부터 계단 꼭대기에 위치한 도착점까지 가는 게임이다. <그림 1>과 같이 각각의 계단에는 일정한 점수가 쓰여 있는데 계단을 밟으면 그 계단에 쓰여 있는 점

www.acmicpc.net

 

 


 

 

 

  • 생각

현재 계단이 i일 때, 그 전 계단 i-1을 밟고 올라왔는지 아닌지로 나눠서 계산한다. 계단을 밟는 개수는 최소가 되어야 하므로 전 단계 i-1을 밟았으면 그 전전 단계 i-2는 점프했다고 가정한다. 그래서 현재 계단까지의 최대값 dp[i]는 지금 계단의 값 steps[i], 전 단계 steps[i-1]과 점프 전 최대값 dp[i-3]의 합이다. 만약 전 단계 i-1을 밟지않고 점프했다면, dp[i]는 현재 값 steps[i]와 점프한 최대값 dp[i-2]의 합이다. 이 둘 중 큰 값을 dp[i]에 저장하면 된다.

 

 

 

 

  • 코드

 

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

public class Main {
	static int n;
	static int[] dp;

	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(dp[n]);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		n = in.nextInt();
		int[] steps = new int[n+1];
		dp = new int[n+1];
		int noJump = 0, jump = 0;
		
		for(int i = 1; i <= n; i++)
			steps[i] = in.nextInt();
		
		dp[1] = steps[1];
		if(n>=2)
			dp[2] = steps[1] + steps[2];
		
		for(int i = 3; i <= n; i++) {
			noJump = steps[i] + steps[i-1] + dp[i-3];
			jump = steps[i] + dp[i-2];
					
			dp[i] = Math.max(noJump, jump);
		}
	}
}
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;
	}
}

 

17141번: 연구소 2

인체에 치명적인 바이러스를 연구하던 연구소에 승원이가 침입했고, 바이러스를 유출하려고 한다. 승원이는 연구소의 특정 위치에 바이러스 M개를 놓을 것이고, 승원이의 신호와 동시에 바이

www.acmicpc.net

 

 


 

 

  • 생각

연구소의 상태가 주어졌을 때, 모든 빈 칸에 바이러스를 퍼뜨리는 최소 시간을 구하는 문제이다.

바이러스 놓을 곳을 선택했다면 배열 복사를 사용해 입력 받은 배열을 복사하고 바이러스를 놓지 않을 곳을 2에서 0으로 바꿔준다. bfs로 바이러스를 전파할 때 2인 곳은 바이러스가 전파되지 않는다.

 

 

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	private static int N, M, count, min;
	private static int[][] array;
	private static boolean[] check;
	private static ArrayList<int[]> virus;
	private static int[] x = { 0, 0, -1, 1 };
	private static int[] y = { -1, 1, 0, 0 };

	public static void main(String[] args) throws Exception {
		SetData();
		System.out.println(min);
	}
	
	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N = in.nextInt();
		M = in.nextInt();
		array = new int[N][N];
		virus = new ArrayList<>();
		min = Integer.MAX_VALUE;
		count = 0;

		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				array[i][j] = in.nextInt();
				if (array[i][j] == 2)
					virus.add(new int[] { i, j });
				if (array[i][j] == 0)
					count++;
			}
		}
		count += virus.size() - M;
		check = new boolean[virus.size()];
		if (count != 0)
			dfs(0, 0);
		else
			min = 0;
		
		if(min == Integer.MAX_VALUE)
			min = -1;
	}

	private static void dfs(int start, int depth) {
		// Basecase
		if (depth == M) {
			int[][] tempArray = copyArray();
			bfs(tempArray, count);
			return;
		}
		for (int i = start; i < virus.size(); i++) {
			check[i] = true;
			dfs(i+1, depth + 1);
			check[i] = false;
		}
	}

	private static void bfs(int[][] tempArray, int count) {
		Queue<int[]> queue = new LinkedList<>();
		for (int i = 0; i < virus.size(); i++) {
			if (check[i])
				queue.add(virus.get(i));
		}
		
		int time = 0;
		while (!queue.isEmpty()) {
			if (time >= min)
				break;
			int len = queue.size();
			for (int j = 0; j < len; j++) {
				int[] location = queue.poll();
				for (int direction = 0; direction < 4; direction++) {
					int r = location[0] + x[direction];
					int c = location[1] + y[direction];
					if (r >= 0 && c >= 0 && r < N && c < N) {
						if (tempArray[r][c] == 0) {
							tempArray[r][c] = 2;
							queue.add(new int[] { r, c });
							count--;
						}
					}
				}
			}
			
			time++;
			if (count == 0) {
				min = time;
				return;
			}
		}
	}

	private static int[][] copyArray() {
		int[][] result = new int[N][N];
		for (int i = 0; i < N; i++) {
			System.arraycopy(array[i], 0, result[i], 0, N);
		}
		for (int i = 0; i < virus.size(); i++) {
			if (!check[i]) {
				int[] location = virus.get(i);
				result[location[0]][location[1]] = 0;
			}
		}
		return result;
	}
}
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;
	}
}

 

2096번: 내려가기

첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.

www.acmicpc.net

 


 

 

 

  • 생각

왼쪽 끝과 오른쪽 끝은 내려갈 수 있는 곳이 2곳으로 한정되어 있고, 중간은 세 곳 모두 갈 수 있으므로 연산을 최대값, 최소값만 찾아서 구해주면 답은 나온다.

 

 

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.InputMismatchException;

public class Main {
	static int N;
	static int[][] dp;

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		SetData();
		System.out.print(dp[N-1][5] + " " + dp[N-1][0]);
	}

	private static void SetData() throws Exception {
		InputReader in = new InputReader(System.in);
		
		N =  in.nextInt();
		int[] input = new int[3];
		dp = new int[N][6];

		for (int i = 0; i < 3; i++)
			input[i] =  in.nextInt();

		for (int i = 0; i < 3; i++)
			dp[0][3 + i] = dp[0][i] = input[i];

		for (int i = 1; i < N; i++) {
			for (int j = 0; j < 3; j++)
				input[j] =  in.nextInt();

			int preIndex = i - 1;

			dp[i][0] = Integer.min(dp[preIndex][0], dp[preIndex][1]) + input[0];
			dp[i][1] = Integer.min(dp[preIndex][0], Math.min(dp[preIndex][1], dp[preIndex][2])) + input[1];
			dp[i][2] = Integer.min(dp[preIndex][1], dp[preIndex][2]) + input[2];

			dp[i][3] = Integer.max(dp[preIndex][3], dp[preIndex][4]) + input[0];
			dp[i][4] = Integer.max(dp[preIndex][3], Math.max(dp[preIndex][4], dp[preIndex][5])) + input[1];
			dp[i][5] = Integer.max(dp[preIndex][4], dp[preIndex][5]) + input[2];
		}

		Arrays.sort(dp[N - 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;
	}
}

 

1987번: 알파벳

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다. 말은 상하좌우로 인접한 네 칸 중의 한 칸으

www.acmicpc.net

 

 


 

 

  • 생각

백트래킹 문제이다. 해당문자가 체크된적 있으면 가장 큰값을 answer에 저장해준다. 체크가 안되있다면 방향을 바꿔주면서 다시 체크한다.

 

내가 짠 코드는 메모리는 적게들지만 시간이 오래걸린다.

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int R, C, answer, array[][];
	static boolean[] check;
	static int[] x = { 0, 1, 0, -1 };
	static int[] y = { 1, 0, -1, 0 };

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

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

		R = in.nextInt();
		C = in.nextInt();
		check = new boolean[26];
		array = new int[R][C];
		answer = 0;

		for (int i = 0; i < R; i++) {
			String s = in.nextLine();
			for (int j = 0; j < C; j++) {
				array[i][j] = s.charAt(j) - 'A';
			}
		}
	}

	public static void dfs(int a, int b, int count) {
		if (check[array[a][b]]) {
			answer = Math.max(answer, count);
			return;
		}

		check[array[a][b]] = true;
		for (int i = 0; i < 4; i++) {
			int r = a + x[i];
			int c = b + y[i];

			if (r < 0 || c < 0 || r >= R || c >= C)	continue;

			dfs(r, c, count + 1);
		}
		check[array[a][b]] = false;

	}
}

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;
	}
}

 

 

 

  • 다른 사람 코드를 보고 좀 더 보완한 코드(재귀식을 queue를 사용하여 비재귀식으로 바꿈)

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int R, C, answer, alphas[][];
	static char[][] array;
	static Queue<int[]> queue;
	static boolean[] check;
	static int[] x = { 0, 1, 0, -1 };
	static int[] y = { 1, 0, -1, 0 };

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

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

		R = in.nextInt();
		C = in.nextInt();
		check = new boolean[26];
		array = new char[R][C];
		alphas = new int[R][C];
		answer = 0;

		for (int i = 0; i < R; i++)
			array[i] = in.nextLine().toCharArray();

		queue = new LinkedList<>();

		queue.add(new int[] { 0, 0, 1 << (array[0][0] - 'a'), 1 });
	}

	public static void dfs() {
		while (!queue.isEmpty()) {

			int[] location = queue.poll();
			if (alphas[location[0]][location[1]] == location[2])	continue;
			alphas[location[0]][location[1]] = location[2];
			answer = location[3];

			for (int i = 0; i < 4; i++) {
				int r = location[0] + x[i];
				int c = location[1] + y[i];

				if (r < 0 || c < 0 || r >= R || c >= C)		continue;

				int next = 1 << (array[r][c] - 'a');

				if ((location[2] & next) == 0) {
					queue.add(new int[] { r, c, location[2] | next, location[3] + 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;
	}
}

 

16194번: 카드 구매하기 2

첫째 줄에 민규가 구매하려고 하는 카드의 개수 N이 주어진다. (1 ≤ N ≤ 1,000) 둘째 줄에는 Pi가 P1부터 PN까지 순서대로 주어진다. (1 ≤ Pi ≤ 10,000)

www.acmicpc.net

 

 

 


 

 

 

  • 생각

 

카드 N개를 구매하는데 최소 비용을 고르는 문제이다.

 

그래서 카드 N개를 구하는 비용을 카드가 N개 들어있는 카드팩으로 초기 설정해주면 쉽게 풀 수 있다.문제를 해석해보면

  • 카드 N개를 구매해야한다.
  • 카드팩에 들어있는 카드가 적은 것부터 산다.
  • 카드 N개를 구매하는데 드는 비용의 최소를 구하는 문제이다.

 

DP를 풀때 일반항 형태로 정의하는 것이 중요하다.

 

일단, 케이스 단위로 생각해보자.

카드 i개를 구매하는 방법은?

  • 카드 1개가 들어있는 카드팩을 구매하고, 카드 i-1개를 구입한다.
  • 카드 2개가 들어있는 카드팩을 구매하고, 카드 i-2개를 구입한다.
  • 카드 3개가 들어있는 카드팩을 구매하고, 카드 i-3개를 구입한다.

 

 

 

  • 코드

 

import java.io.IOException;
import java.io.InputStream;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;

public class Main {
	static int N, dp[], array[];

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

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

		N = in.nextInt();
		array = new int[N + 1];
		dp = new int[N + 1];

		for (int i = 1; i <= N; i++) 
			array[i] = in.nextInt();
	}

	private static void dp() {
        for(int i = 1; i <= N; i++){
            dp[i] = array[i];
            for(int j = 1; j <= i; j++){
                dp[i] = Math.min(dp[i], dp[i-j]+array[j]);
            }
        }
	}
}

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