17406번: 배열 돌리기 4

크기가 N×M 크기인 배열 A가 있을때, 배열 A의 값은 각 행에 있는 모든 수의 합 중 최솟값을 의미한다. 배열 A가 아래와 같은 경우 1행의 합은 6, 2행의 합은 4, 3행의 합은 15이다. 따라서, 배열 A의

www.acmicpc.net

 

 


 

 

  • 생각

 

배열 N x M 에서 K번 회전 기회가 주어진다.

r, c, s가 주어지면 (r-s, c-s) 부터 (r+s, c+s)까지 직사각형별로 오른쪽으로 한칸씩 돌리면 된다.

돌린 후 각 행의 값을 다 더했을 때 가장 작은 값을 찾는 문제이다.

 

이대로 했는데, 틀렸다. 문제는 K번 index가 주어질 때 순서대로 회전을 시키는 것이 아닌 순서와 상관없이 돌렸을 때 가장 작은 행의 값을 찾는 문제였다.

 

후에 모든 K(r, c, s)의 순서를 바꿔가면서 위의 방법을 반복해서 풀었다.

 

 

 

 

  • 코드

 

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

public class Main {
	static int N, M, K, answer;
	static int[][] array, tempArray, rcs;
	static boolean[] check;
	static int[] x = { -1, 1, 0, 0 };
	static int[] y = { 0, 0, -1, 1 };

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

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

		N = in.nextInt();
		M = in.nextInt();
		K = in.nextInt();
		array = new int[N][M];
		tempArray = new int[N][M];
		answer = Integer.MAX_VALUE;

		for (int i = 0; i < N; i++) {
			for (int j = 0; j < M; j++) {
				array[i][j] = in.nextInt();
				tempArray[i][j] = array[i][j];
			}
		}

		rcs = new int[K][3];
		for (int i = 0; i < K; i++) {
			rcs[i][0] = in.nextInt() - 1;
			rcs[i][1] = in.nextInt() - 1;
			rcs[i][2] = in.nextInt();
		}
	}

	public static void RotateArray() {
		int[] order = new int[K];
		for(int i = 0; i < K; i++)
			order[i] = i;
		
		while(true) {
			// 여기서 최대값 찾기 ( 회전 연산 ) 
			for (int n : order) {// 회전 순서
				int r = rcs[n][0], c=rcs[n][1], s = rcs[n][2];
				while(s>0) {
					int a = array[r-s][c-s];
					for(int i = r-s; i+1<=r+s;i++) {
						array[i][c-s] = array[i+1][c-s];
					}
					for(int i = c-s;i+1<=c+s;i++) {
						array[r+s][i] = array[r+s][i+1];
					}
					for(int i = r+s;i-1>=r-s;i--) {
						array[i][c+s] = array[i-1][c+s];
					}
					for(int i = c+s; i-1>=c-s;i--) {
						array[r-s][i] = array[r-s][i-1];
					}
					array[r-s][c-s+1] = a;
					if(--s==0)break;
				}
				
			}
			
			// 최소 행 찾기
			for(int i = 0; i<N;i++) {
				int temp = 0; 
				for (int j = 0; j < M; j++) {
					temp+=array[i][j];
				}
				answer = temp<answer?temp:answer;
			}
			
			// 원래 배열로 back
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < M; j++) {
					array[i][j] = tempArray[i][j];
				}
			}
			
			// 순서 바굼
			int f = K-2;
			for (; f>=0  ; f--) {
				if(order[f]<order[f+1])break;
			}
			if(f==-1)break;			
			int l = K-1;
			for(;l>f;l--) {
				if(order[f]<order[l])break;
			}			
			int temp = order[f];
			order[f]= order[l];
			order[l] = temp;
			++f;
			for(int i = K-1;i>f;i--,f++) {
				temp = order[i];
				order[i]= order[f];
				order[f] = 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;
	}
}

 

2210번: 숫자판 점프

111111, 111112, 111121, 111211, 111212, 112111, 112121, 121111, 121112, 121211, 121212, 211111, 211121, 212111, 212121 이 가능한 경우들이다.

www.acmicpc.net

 

 


 

 

  • 생각

 

모든 경우의 수를 확인해야 되는 문제이다.

 

dfs 방식

1. 파라미터는 현재 index(a, b), 숫자가 몇개인지(depth), 현재 숫자(number) 이다.

2. basecase는 숫자가 몇개인지를 체크해서 6개가 되고 이전에 없던 숫자이면 answer을 ++하고 return해준다.

3. 체크하는 방법은 boolean으로 1000001개를 만들어 index로 체크한다. (hashset으로 했었는데 더 느리다.)

4. 상, 하, 좌, 우를 돌리면서 (이전 숫자*10 + 현재 숫자), 다음 index, depth를 바꿔주면서 dfs를 돌린다.

 

 

 

  • 코드

 

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

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

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

		array = new int[5][5];
		check = new boolean[1000001];
		answer = 0;

		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				array[i][j] = in.nextInt();
			}
		}

		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				dfs(i, j, 0, array[i][j]);
			}
		}
	}

	public static void dfs(int a, int b, int depth, int number) {
		// basecase
		if (depth == 5) {
			if (!check[number]) {
				check[number] = true;
				answer++;
			}
			return;
		}
		
		// 6번 까지 모든 경우의 수 이동
		for (int i = 0; i < 4; i++) {
			int r = a + x[i];
			int c = b + y[i];

			if (r < 0 || c < 0 || r >= 5 || c >= 5) 	continue;
			dfs(r, c, depth + 1, number * 10 + array[r][c]);

		}

	}
}

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

 

16637번: 괄호 추가하기

첫째 줄에 수식의 길이 N(1 ≤ N ≤ 19)가 주어진다. 둘째 줄에는 수식이 주어진다. 수식에 포함된 정수는 모두 0보다 크거나 같고, 9보다 작거나 같다. 문자열은 정수로 시작하고, 연산자와 정수가

www.acmicpc.net

 

 


 

 

  • 생각

 

연산은 왼쪽부터 오른쪽으로 순서대로 진행된다. (*, / 연산에 대한 우선순위 없다.)

단, 괄호의 우선순위는 있다. 괄호는 랜덤으로 어디에나 추가될 수가 있다.

 

오래 고민해보니 모든 경우의 수를 훑어야하는 작업일 것 같다라는 생각이 들었다.

고안해낸 방식은 dfs방식이다.

 

 

dfs 방식

1. dfs 파라미터는 연산자인덱스, 현재까지의 합이다. 

2. basecase는 연산기호를 모두 사용했을 때이다. (현재까지의 합이 가장 크다면 업데이트)

3. 괄호가 없는 경우 (연산자의 왼쪽 숫자와 오른쪽 숫자를 연산한 뒤 dfs를 돈다.)

4. 괄호가 있는 경우 (현재 연산자의 바로 뒤 연산자 먼저 연산하고, 현재 연산자를 연산한 뒤 dfs를 돈다.)

 

 

 

  • 코드

 

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

public class Main {
	static int N, answer;
	static int[] number;
	static char[] operator;

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

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

		N = in.nextInt();
		answer = Integer.MIN_VALUE;
		number = new int[N / 2 + 1];
		operator = new char[N / 2];

		String temp = in.nextLine();
		int indexOfNumber = 0;
		int indexOfChar = 0;
		for (int i = 0; i < N; i++) {
			if (i % 2 == 0) {
				number[indexOfNumber++] = Integer.parseInt(temp.charAt(i) + "");
			} else {
				operator[indexOfChar++] = temp.charAt(i);
				;
			}
		}
	}

	public static void dfs(int operatorIndex, int sum) {
		// basecase
		if (operatorIndex >= N / 2) {
			answer = Math.max(answer, sum);
			return;
		}

		// 괄호 안치고 진행하기
		int nobracket = Calculator(operatorIndex, sum, number[operatorIndex + 1]);
		dfs(operatorIndex + 1, nobracket);

		// 더이상 할 작업이 없으면 return
		if (operatorIndex + 1 >= N / 2)
			return;

		// 괄호 치고 진행하기
		int bracket = Calculator(operatorIndex + 1, number[operatorIndex + 1], number[operatorIndex + 2]);
		int result = Calculator(operatorIndex, sum, bracket);
		dfs(operatorIndex + 2, result);

	}

	public static int Calculator(int operatorIndex, int a, int b) {
		switch (operator[operatorIndex]) {
		case '+':
			return a + b;
		case '-':
			return a - b;
		case '*':
			return a * b;
		}
		return 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;
	}
}

 

2110번: 공유기 설치

첫째 줄에 집의 개수 N (2 ≤ N ≤ 200,000)과 공유기의 개수 C (2 ≤ C ≤ N)이 하나 이상의 빈 칸을 사이에 두고 주어진다. 둘째 줄부터 N개의 줄에는 집의 좌표를 나타내는 xi (0 ≤ xi ≤ 1,000,000,000)가

www.acmicpc.net

 

 


 

 

  • 생각

1. 단순 O(n^2)으로는 시간 초과가 뜰 것 같다.

 

2. 이분 탐색을 사용해도 될 것 같다. 특정한 간격을 기준으로 가능한 위치에 공유기 설치, 설치 후 공유기 수가 더 설치되야하면 간격을 줄임. 공유기 수를 줄여야 한다면 간격을 늘림.

 

 

 

  • 코드

정답 코드 : 이분탐색을 통해 구현

 

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

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

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

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

		N = in.nextInt();
		C = in.nextInt();

		array = new int[N];
		for (int i = 0; i < N; i++)
			array[i] = in.nextInt();
		Arrays.sort(array);
	}

	private static int SearchBinary() {
		int left = 1;
		int right = array[N - 1] - array[0];
		int d = 0;
		int value = 0;

		while (left <= right) {
			int mid = (left + right) / 2;
			int start = array[0];
			int count = 1;
			for (int i = 0; i < N; i++) { // 집집마다 검색함.
				d = array[i] - start;
				if (d >= mid) { // 만약 첫번째 집과의 거리가 더 크다면 찾았다고 count 올려주고, 내가 찾는집에 이번 집을 넣어준다.
					count++;
					start = array[i];
				}
			}

			if (count >= C) {
				value = mid;
				left = mid + 1;
			} else {
				right = mid - 1;
			}
		}
		return 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;
	}
}

 

1107번: 리모컨

첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다.  둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼

www.acmicpc.net

 

 


 

  • 생각

 

문제는 리모컨을 눌러서 채널 N을 트는 것이다.

 

조건)

1. 처음 시작은 100번이다.

2. 고장난 번호가 있다.

3. 번호를 누르는 것 외로 +,-를 사용할 수 있다.

 

풀이)

1. 처음 시작 채널 100에서 채널 N을 +,-로만 틀 떄의 누르는 횟수를 answer에 저장한다.(Math.abs를 사용하면 편리)

2. 고장난 번호는 boolean 배열을 이용해서 해당 index에 true로 설정해놓는다. (배열의 false index는 사용가능)

3. dfs를 돌린다.

4. basecase는 현재 채널이 채널 N의 길이보다 길어지면 그만 돌린다. (채널 N의 길이보다 +1 을 해줘야한다.)

 **현재 길이보다 +1 해준 이유는 값이 9999이런식으로 가는데 9를 쓰지 못하는 경우 +1을 해주지않으면 8888에서         +로 9999를 만들어야 하는데, +1해주면 10000에서 -한번만 누르면 가능함.

5. basecase에 걸리지 않으면 현재 채널까지 누른 횟수에서 +,-를 사용해서 채널 N을 만들 때의 누른 횟수를 answer로 초기화 시킨다.

6. 반복문으로 채널 0~9번을 누르면서 dfs를 돌린다. (고장난 버튼은 누르지 않음)

 

 

 

  • 코드

 

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

public class Main {
	static int N, answer, limit;
	static boolean[] array;

	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.nextInt();
		array = new boolean[10];
		// 현재 길이보다 +1 해준 이유는 값이 9999이런식으로 가는데 9를 쓰지 못하는 경우 +1을 해주지않으면 8888에서 +로 9999를 만들어야 하는데
		// +1해주면 10000에서 -한번만 누르면 가능함.
		limit = (N+"").length() + 1;

		int numberOfBrokenRemoteControl = in.nextInt();
		for (int i = 0; i < numberOfBrokenRemoteControl; i++)
			array[in.nextInt()] = true;

		// 초기값 100에서 +,-만 사용해서채널 N을 틀 때 누르는 수
		answer = Math.abs(N - 100);
		
		for (int i = 0; i < 10; i++) {
			if (array[i])
				continue;
			
			dfs(i, 1);
		}
	}

	private static void dfs(int value, int count) {
		// basecase (현재 수가 N보다 높아지면 그만 돌린다.)
		if (limit < count)
			return;

		// 현재 누른 횟수와 +,-만 사용해서 채널 N을 틀 때 누르는 수
		answer = Math.min(answer, count + Math.abs(N - value));
		for (int i = 0; i < 10; i++) {
			if (array[i])
				continue;
			
			dfs((value * 10) + i, count + 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;
	}
}

 

 

 

  • 다른 사람 코드

가져온 이유) 내 코드보다 시간이 5배 정도 빠르다. 공부해볼 필요가 있다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int m = Integer.parseInt(br.readLine());
        int ret = (n > 100)? n - 100 : 100 - n;
        boolean[] isBrokenButton;
        StringTokenizer st;
        
        if(m == 0) {
            System.out.print((String.valueOf(n).length() < ret)? String.valueOf(n).length() : ret);
            return;
        }
        
        st = new StringTokenizer(br.readLine());
        isBrokenButton = new boolean[10];
        
        if(n == 100) {
            System.out.print(0);
            return;
        } else if(m == 10) {
            System.out.print(ret);
            return;
        }
        
        while(st.hasMoreTokens())
            isBrokenButton[Integer.parseInt(st.nextToken())] = true;

        System.out.print(getPushCountOfButtonsToMoveChannel(n, isBrokenButton));
    }
    
    private static int getPushCountOfButtonsToMoveChannel(int destChannel, boolean[] isBrokenButton) {
        int ret = (destChannel > 100)? destChannel - 100 : 100 - destChannel;
        int lowChannel = -1, highChannel = -1, maxChannel = 100;
        int divider = (destChannel > 0)? ((int) Math.pow(10, (int) Math.log10(destChannel))) : 1;
        boolean isBrokenDestChannel = false;

        for(int i = divider; i > 0; i /= 10) {
            if(isBrokenButton[destChannel / i % 10]) {
                isBrokenDestChannel = true;
                break;
            }
        }
        
        if(!isBrokenDestChannel) {
            int retOfDestChannel = String.valueOf(destChannel).length();
            return (retOfDestChannel < ret)? retOfDestChannel : ret;
        }
        
        for(int i = 0; i < (int) Math.log10(destChannel); i++)
            maxChannel *= 10;
        
        for(int i = destChannel - 1; i >= 0; i--) {
            boolean isBrokenLowChannel = false;
            int brokenDivider = 0;
            
            divider = (i > 0)? ((int) Math.pow(10, (int) Math.log10(i))) : 1;
            
            for(int j = divider; j > 0; j /= 10) {
                if(isBrokenButton[i / j % 10]) {
                    isBrokenLowChannel = true;
                    brokenDivider = j;
                    break;
                }
            }

            if(isBrokenLowChannel) {
                i -= i % brokenDivider;
            } else {
                lowChannel = i;
                break;
            }
        }

        for(int i = destChannel + 1; i < maxChannel; i++) {
            boolean isBrokenHighChannel = false;
            int brokenDivider = 0;
            
            divider = (i > 0)? ((int) Math.pow(10, (int) Math.log10(i))) : 1;
            
            for(int j = divider; j > 0; j /= 10) {
                if(isBrokenButton[i / j % 10]) {
                    isBrokenHighChannel = true;
                    brokenDivider = j;
                    break;
                }
            }

            if(isBrokenHighChannel) {
                i -= i % brokenDivider;
                i += brokenDivider - 1;
            } else {
                highChannel = i;
                break;
            }
        }
        
        if(lowChannel > -1) {
            int retOfLowChannel = String.valueOf(lowChannel).length();
            
            retOfLowChannel += destChannel - lowChannel;
            ret = (retOfLowChannel < ret)? retOfLowChannel : ret;
        }

        if(highChannel > -1) {
            int retOfHighChannel = String.valueOf(highChannel).length();
            
            retOfHighChannel += highChannel - destChannel;
            ret = (retOfHighChannel < ret)? retOfHighChannel : ret;
        }
        
        return ret;
    }
    
}

 

9461번: 파도반 수열

오른쪽 그림과 같이 삼각형이 나선 모양으로 놓여져 있다. 첫 삼각형은 정삼각형으로 변의 길이는 1이다. 그 다음에는 다음과 같은 과정으로 정삼각형을 계속 추가한다. 나선에서 가장 긴 변의

www.acmicpc.net

 

 


 

  • 생각

 

DP문제이다. index 5까지만 반복해서 보면 dp[i] = di[i-2] + dp[i-3]이 점화식이 되는 것을 쉽게 알 수 있다.

 

 

 

  • 코드

 

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

public class Main {
	static StringBuilder sb;
	static long[] dp;
	
	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 N = in.nextInt();    
		sb = new StringBuilder();
        dp = new long[101];
        dp[1] = 1;
        dp[2] = 1;
        dp[3] = 1;
        
        Solve(in, N);
	}
	
	private static void Solve(InputReader in, int N) {
        for(int i = 4; i < 101; i++) 
        	dp[i] = dp[i-2] + dp[i-3];
        
        for(int i = 0; i< N; i++)
        	sb.append(dp[in.nextInt()]).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;
	}
}

 

15886번: 내 선물을 받아줘 2

욱제는 구사과의 열렬한 팬이다. 오늘 욱제는 구사과에게 선물()을 전달해주려고 한다. 지난 며칠간의 관찰 끝에 욱제는 구사과의 이동 패턴을 모두 파악했다. 구사과가 있는 곳은 1×N 크기의 직

www.acmicpc.net


 

  • 생각

 

입력한 문자열을 n-2까지 보면서 현재 index 값이 E이면서 index+1값이 W이면 value값, i값을 증가

 

 

 

  • 코드

 

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

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

		int N = in.nextInt();
		String s = in.nextLine();
		answer = 0;
		
		Solve(N, s);
	}
	
	private static void Solve(int N, String s) {
        for (int i = 0; i < N - 1; i++) {
        	if (s.charAt(i) != 'E' || s.charAt(i+1) != 'W') 
        		continue;
        	
        	answer++;
            i++;
        }
	}
}

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

 

 

9372번: 상근이의 여행

첫 번째 줄에는 테스트 케이스의 수 T(T ≤ 100)가 주어지고, 각 테스트 케이스마다 다음과 같은 정보가 주어진다. 첫 번째 줄에는 국가의 수 N(2 ≤ N ≤ 1 000)과 비행기의 종류 M(1 ≤ M ≤ 10 000) 가

www.acmicpc.net

 

 


 

  • 생각

모든 국가를 지나도록 이용할 수 있는 최소의 비행기의 개수는 국가의 수-1

 

 

  • 코드

 

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

public class Main {
	static StringBuilder sb;
	
	public static void main(String[] args) throws Exception {
		SetData();
	}

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

		int num = in.nextInt();
		sb = new StringBuilder();

		for (int i = 0; i < num; i++) {
			Solve(in, out);
		}
		
		out.print(sb);
		out.close();
	}
	
	private static void Solve(InputReader in, PrintWriter out) {
		int country = in.nextInt();
		int plane = in.nextInt();

		for (int j = 0; j < plane; j++) {
			in.nextInt();
			in.nextInt();
		}

		sb.append(country - 1 + "\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 readString() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	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