문제 설명 및 풀이

1. 3 * 2 일 때 만들 수 있는 경우 3 가지
2. 3 * 4 부터 2 * 2 를 추가할 수 있다. 그래서 2 가지 더해주고
3. 3 * 6 일 때 또 패턴 생기고 쭉 생김

증명

솔직히 증명은 못하겠다. (다른 블로그들을 참고했기 때문이다.)
1. 비트마스크로 구하고 DP 하는 방법도 있다한다. 그건 증명이 가능할듯

코드

문제

3×N 크기의 벽을 2×1, 1×2 크기의 타일로 채우는 경우의 수를 구해보자.

입력

첫째 줄에 N(1 ≤ N ≤ 30)이 주어진다.

출력

첫째 줄에 경우의 수를 출력한다.

예제 입력 1 

2

예제 출력 1 

3

힌트

아래 그림은 3×12 벽을 타일로 채운 예시이다.


문제 설명

1. 하이픈으로 나눠진 성(first name)이 존재한다.
2. 성의 첫 번째 글자들만 모아서 출력하면 된다.

풀이

1. StringTokenizer 로 하이픈 기준으로 잘라서 출력

코드

문제

KMP 알고리즘이 KMP인 이유는 이를 만든 사람의 성이 Knuth, Morris, Prett이기 때문이다. 이렇게 알고리즘에는 발견한 사람의 성을 따서 이름을 붙이는 경우가 많다.

또 다른 예로, 유명한 비대칭 암호화 알고리즘 RSA는 이를 만든 사람의 이름이 Rivest, Shamir, Adleman이다.

사람들은 이렇게 사람 성이 들어간 알고리즘을 두 가지 형태로 부른다.

  • 첫 번째는 성을 모두 쓰고, 이를 하이픈(-)으로 이어 붙인 것이다. 예를 들면, Knuth-Morris-Pratt이다. 이것을 긴 형태라고 부른다.
  • 두 번째로 짧은 형태는 만든 사람의 성의 첫글자만 따서 부르는 것이다. 예를 들면, KMP이다.

동혁이는 매일매일 자신이 한 일을 모두 메모장에 적어놓는다. 잠을 자기 전에, 오늘 하루 무엇을 했는지 되새겨보는 것으로 하루를 마감한다.

하루는 이 메모를 보던 중, 지금까지 긴 형태와 짧은 형태를 섞어서 적어논 것을 발견했다.

이렇게 긴 형태로 하루 일을 기록하다가는 메모장 가격이 부담되어 파산될 것이 뻔하기 때문에, 앞으로는 짧은 형태로 기록하려고 한다.

긴 형태의 알고리즘 이름이 주어졌을 때, 이를 짧은 형태로 바꾸어 출력하는 프로그램을 작성하시오.

입력

입력은 한 줄로 이루어져 있고, 최대 100글자의 영어 알파벳 대문자, 소문자, 그리고 하이픈 ('-', 아스키코드 45)로만 이루어져 있다. 첫번째 글자는 항상 대문자이다. 그리고, 하이픈 뒤에는 반드시 대문자이다. 그 외의 모든 문자는 모두 소문자이다.

출력

첫 줄에 짧은 형태 이름을 출력한다.

예제 입력 1 

Knuth-Morris-Pratt

예제 출력 1 

KMP



문제

  예제를 보고 별찍는 규칙을 유추한 뒤에 별을 찍어 보세요.

입력

  첫째 줄에 N (1<=N<=100) 주어진다.

출력

  첫째 줄부터 2*N-1번째  까지 차례대로 별을 출력한다.

예제 입력 1 

3

예제 출력 1 

  *
 **
***
 **
  *

출처


문제 설명

1. Mi 의 숫자가 N 에 존재하는지 출력하는 문제

풀이

1. 이분탐색을 사용하라고 문제 분류가 돼있지만, 더 빠른 풀이를 위해 BitSet 을 사용했다.
2. 이분탐색을 사용하면 O(MlgN + NlgN) 정렬하고 찾는 시간이고, BitSet 을 사용하면(N+M) 이다.
3. 메모리 제한도 높고, Mi 의 제한도 높지 않아서 쉽게 풀 수 있었다.
4. JAVA 로 약 680MS 로 정답이니 거의 엄청 빠른 퍼포먼스를 낼 수 있었다. (첫 제출은 790MS 정도였다. 이유는 숫자 + 문자열을 write 해줬기 때문이다. 변경된 것은 문자열로만 되게)

코드

문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 숫자 M개가 주어졌을 때, 이 숫자가 적혀있는 숫자 카드를 상근이가 가지고 있는지 아닌지를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N (1 ≤ N ≤ 500,000)이가 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 숫자가 주어진다. 숫자 카드에 적혀있는 숫자는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 두 숫자 카드에 같은 숫자가 적혀있는 경우는 없다.

셋째 줄에는 M (1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 가지고 있는 숫자 카드인지 아닌지를 구해야 할 M개의 숫자가 주어지며, 이 숫자는 공백으로 구분되어져 있다. 이숫자도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다

출력

첫째 줄에 입력으로 주어진 M개의 숫자에 대해서, 각 숫자가 적힌 숫자 카드를 상근이가 가지고 있으면 1을, 아니면 0을 공백으로 구분해 출력한다.

예제 입력 1 

5
6 3 2 10 -10
8
10 9 -5 2 3 4 5 -10

예제 출력 1 

1 0 0 1 1 0 0 1

출처


문제 설명

1. 문제에서 제시하는 모양으로 별을 찍으면 된다.
2. 풀고나서 생각난건데 character 배열에 하면 두 삼각형을 겹쳐서 만들고 출력해줘도 됐을 것 같다.

풀이

1. 위의 삼각형은 꼭짓점 하나를 없애고 출력한다.
2. 밑의 삼각형은 꼭짓점이 3 개 다 있는 상태로 출력한다.
3. 위의 삼각형은 (N - i) * 2 + 1 개 별을 출력
4. 밑의 삼각형은 (i - 1)* 2 + 1 개의 별을 출력
5. i 는 시작줄의 개수 1부터 시작

코드


문제

예제를 보고 별찍는 규칙을 유추한 뒤에 별을 찍어 보세요.

입력

첫째 줄에 N (1<=N<=100)이 주어진다.

출력

첫째 줄부터 2*N-1번째 줄 까지 차례대로 별을 출력한다.

예제 입력 1 

5

예제 출력 1 

*********
 *******
  *****
   ***
    *
   ***
  *****
 *******
*********

출처


문제 설명

1. 숫자들의 제곱 합을 10 으로 나눴을 때, 나머지를 출력하면 된다.

풀이

1. Math.pow 라는 메소드를 사용해 제곱연산 (변수로 선언하고 변수 * 변수 했어도 됨)

코드

문제

컴퓨터를 제조하는 회사인 KOI 전자에서는 제조하는 컴퓨터마다 6자리의 고유번호를 매긴다. 고유번호의 처음 5자리에는 00000부터 99999까지의 수 중 하나가 주어지며 6번째 자리에는 검증수가 들어간다. 검증수는 고유번호의 처음 5자리에 들어가는 5개의 숫자를 각각 제곱한 수의 합을 10으로 나눈 나머지이다.

예를 들어 고유번호의 처음 5자리의 숫자들이 04256이면, 각 숫자를 제곱한 수들의 합 0+16+4+25+36 = 81 을 10으로 나눈 나머지인 1이 검증수이다.

입력

첫째 줄에 고유번호의 처음 5자리의 숫자들이 빈칸을 사이에 두고 하나씩 주어진다.

출력

첫째 줄에 검증수를 출력한다.

예제 입력 1 

0 4 2 5 6

예제 출력 1 

1


문제 설명

1. (1,1) 에서 시작 오른쪽, 밑, 대각선 이동 가능
2. 대각선으로 가는 경우는 오른쪽 또는 밑을 거쳐서 가는것보다 학상 작거나 같다. (음수가없음)

풀이

1. M 길이의 줄이 N 개 있다고 생각하고 풀었다. (최단거리를 찾는 문제랑 같음(도로에서 갈림길))
2. 오른쪽으로 가는 최대값은 항상 최대니 밑으로 내려가는 경우를 구해야됐다.
3. 밑으로 가는 경우에서 최대값은 왼쪽에서 오거나 바로 위에서 오는 경우이다.
4. 그래서 max(dp 배열의 현재 위치, dp 배열의 현재 위치에서의 왼쪽) 을 구해주면 된다.

증명

1. dp[1] 은 항상 최대값이다. (아래로 가는 경우만 존재)
2. dp[i] 에는 왼쪽 혹은 위에서 내려온 경우가 최대값이 된다.
첫 번째 줄만 생각해보자
dp[2] 를 구해야 하는 경우 왼쪽에서 오는 경우면 항상 최대값이다.
두 번째 줄을 생각해보면, 
dp[1] 은 이전의 dp[1] 이 최대값이다. 그러면 dp[2] 도 최대값이 들어가게 된다. (dp[1] 을 구하는 방식이랑 똑같이 하게되면)

코드

문제

준규는 N×M 크기의 미로에 갇혀있다. 미로는 1×1크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여져 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다.

준규는 현재 (1, 1)에 있고, (N, M)으로 이동하려고 한다. 준규가 (r, c)에 있으면, (r+1, c), (r, c+1), (r+1, c+1)로 이동할 수 있고, 각 방을 방문할 때마다 방에 놓여져있는 사탕을 모두 가져갈 수 있다. 또, 미로 밖으로 나갈 수는 없다.

준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수의 최대값을 구하시오.

입력

첫째 줄에 미로의 크기 N, M이 주어진다. (1 ≤ N, M ≤ 1,000)

둘째 줄부터 N개 줄에는 총 M개의 숫자가 주어지며, r번째 줄의 c번째 수는 (r, c)에 놓여져 있는 사탕의 개수이다. 사탕의 개수는 0보다 크거나 같고, 100보다 작거나 같다.

출력

첫째 줄에 준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수를 출력한다.

예제 입력 1 

3 4
1 2 3 4
0 0 0 5
9 8 7 6

예제 출력 1 

31

예제 입력 2 

3 3
1 0 0
0 1 0
0 0 1

예제 출력 2 

3

예제 입력 3 

4 3
1 2 3
6 5 4
7 8 9
12 11 10

예제 출력 3 

47

출처


문제 설명

1. 알파뱃이 몇 번 나왔는지 출력해주면 됨

풀이

1. 문자열에서 한 문자씩 확인

더 빠른 방법: 문자열로 기록 x -> 문자로 받고 바로바로 연산하면 엄청 빨라질듯 하다. (공간복잡도 O(1))

코드

문제

알파벳 소문자로만 이루어진 단어 S가 주어진다. 각 알파벳이 단어에 몇 개가 포함되어 있는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 단어 S가 주어진다. 단어의 길이는 100을 넘지 않으며, 알파벳 소문자로만 이루어져 있다.

출력

단어에 포함되어 있는 a의 개수, b의 개수, …, z의 개수를 공백으로 구분해서 출력한다.

예제 입력 1 

baekjoon

예제 출력 1 

1 1 0 0 1 0 0 0 0 1 1 0 0 1 2 0 0 0 0 0 0 0 0 0 0 0


문제 설명

1. 스티커가 2줄로 있다.
2. 연속으로 사용하지 않고, 최대한 많이 점수를 획득하라

풀이

1. dp 로 풀고, bottom-up 방식으로 풀었다.
2. 사선으로 뽑거나 건너띄고 뽑거나

증명

1. dp[1][0] = stickers[1][0] 이 최대값이다. [0][0]도 마찬가지
2. dp[x][i] = 사선으로 뽑은거 + stickers[x][i] 또는 dp[x][i - 1] 중 큰 값을 넣게되면 그 당시에 최대값이 들어가게 된다.
3. 2 번을 반복해서 앞으로 점점 가다보면, 그 상황에서의 최대값을 계속 사용하기 때문에 확장시켜서 보면 결론적으로는 최대값이 들어가게 된다.

코드

문제

상근이의 여동생 상냥이는 문방구에서 스티커 2n개를 구매했다. 스티커는 그림 (a)와 같이 2행 n열로 배치되어 있다. 상냥이는 스티커를 이용해 책상을 꾸미려고 한다.

상냥이가 구매한 스티커의 품질은 매우 좋지 않다. 스티커 한 장을 떼면, 그 스티커와 변을 공유하는 스티커는 모두 찢어져서 사용할 수 없게 된다. 즉, 뗀 스티커의 왼쪽, 오른쪽, 위, 아래에 있는 스티커는 사용할 수 없게 된다.

모든 스티커를 붙일 수 없게된 상냥이는 각 스티커에 점수를 매기고, 점수의 합이 최대가 되게 스티커를 떼어내려고 한다. 먼저, 그림 (b)와 같이 각 스티커에 점수를 매겼다. 상냥이가 뗄 수 있는 스티커의 점수의 최대값을 구하는 프로그램을 작성하시오. 즉, 2n개의 스티커 중에서 점수의 합이 최대가 되면서 서로 변을 공유 하지 않는 스티커 집합을 구해야 한다.

위의 그림의 경우에 점수가 50, 50, 100, 60인 스티커를 고르면, 점수는 260이 되고 이 것이 최대 점수이다. 가장 높은 점수를 가지는 두 스티커 (100과 70)은 변을 공유하기 때문에, 동시에 뗄 수 없다.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의 점수이다. 연속하는 두 정수 사이에는 빈 칸이 하나 있다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다. 

출력

각 테스트 케이스 마다, 2n개의 스티커 중에서 두 변을 공유하지 않는 스티커 점수의 최대값을 출력한다.

예제 입력 1 

2
5
50 10 100 20 40
30 50 70 10 60
7
10 30 10 50 100 20 40
20 40 30 50 60 20 80

예제 출력 1 

260
290


문제 설명

1. 1로 이루어진 영역이 존재한다. (상하좌우 그룹)
2. 영역의 개수를 구하면 된다.

풀이

1. DFS, BFS 로 풀이가 가능하다.
2. DFS 가 코드가 더 깔끔하므로, DFS 를 사용한다.
3. for loop 를 사용하고, 모든 칸을 다 확인하고 그 영역들을 다 0으로 만들어줌

증명

1. (x, y) 를 dfs 로 시작한다 하면, 상하좌우가 1인 경우 그 칸을 또 dfs(x1, y1) 로 실행한다.
2. 그러면 영역이 모두 0이 된다.
3. for loop 을 돌면서 모든 칸을 검사하면 영역 0 만들고 다른 영역을 찾기 때문에 정답이다.

수식을 세우고 하면 좀 더 간단하게 할 수 있을 것 같은데, 그정도까지는 아직 못하겠다.

코드

문제

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추흰지렁이를 구입하기로 결심한다. 이 지렁이는 배추근처에 서식하며 해충을 잡아 먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추흰지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다.

(한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해있다고 간주한다)

한나가 배추를 재배하는 땅은 고르지 못해서 배추를 군데군데 심어놓았다. 배추들이 모여있는 곳에는 배추흰지렁이가 한 마리만 있으면 되므로 서로 인접해있는 배추들이 몇 군데에 퍼져있는지 조사하면 총 몇 마리의 지렁이가 필요한지 알 수 있다.

예를 들어 배추밭이 아래와 같이 구성되어 있으면 최소 5마리의 배추흰지렁이가 필요하다.

(0은 배추가 심어져 있지 않은 땅이고, 1은 배추가 심어져 있는 땅을 나타낸다.)

1100000000
0100000000
0000100000
0000100000
0011000111
0000100111

입력

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 첫째 줄에는 배추를 심은 배추밭의 가로길이 M(1 ≤ M ≤ 50)과 세로길이 N(1 ≤ N ≤ 50), 그리고 배추가 심어져 있는 위치의 개수 K(1 ≤ K ≤ 2500)이 주어진다. 그 다음 K줄에는 배추의 위치 X(0 ≤ X ≤ M-1), Y(0 ≤ Y ≤ N-1)가 주어진다.

출력

각 테스트 케이스에 대해 필요한 최소의 배추흰지렁이 마리 수를 출력한다.

예제 입력 1 

2
10 8 17
0 0
1 0
1 1
4 2
4 3
4 5
2 4
3 4
7 4
8 4
9 4
7 5
8 5
9 5
7 6
8 6
9 6
10 10 1
5 5

예제 출력 1 

5
1

출처


+ Recent posts