문제 설명

중복된 수를 구하면 된다.

풀이

1. Bitset 을 사용하는 방법
bitset 은 bit 의 0 1 로 그 숫자가 있나 없나 확인하는 테크닉이다.
나중에 직접 구현해보면서 자세하게 적겠다.
2. 등차수열의 합을 이용하는 방법
S = N(N - 1)/2 + M
M = S - N(N - 1)/2


ISKU 님의 Buffer read 부분을 참고했습니다.

해답


문제

1부터 N - 1까지의 정수가 하나씩 정렬되지 않은 채로 저장되어 있는 어떤 수열 A가 있다. 수열 A에 임의의 정수 M(1 ≤ M ≤ N – 1)을 넣어 크기가 N인 수열로 만들었을 때, 임의의 정수 M을 찾는 프로그램을 작성하라.

입력

첫째줄에 수열의 크기 N(2 ≤ N ≤ 10,000,000)이 주어진다.

둘째줄에 수열 A의 원소인 N개의 정수가 주어진다. 입력으로 주어지는 정수는 모두 1부터 N – 1 사이의 정수이며 문제의 답인 M을 제외하고는 모두 서로 다른 정수이다.

출력

M을 출력하라.

예제 입력 1 

10
1 2 2 5 6 4 3 7 8 9

예제 출력 1 

2


문제 설명

1. 전쟁에서 누가 승리하는지를 알아내면 된다.
2. 전쟁에서 승리하는 기준은 점수가 높으면 된다.
3. 점수의 합은 정수이고, 32비트가 넘지 않는다. -> int 형으로 충분하다.

풀이 과정

코드를 작성하기 전에 이 문제는 너무 쉽다는 걸 알게돼, 만약 어떻게 이 문제의 코드를 짧게 짤 수 있을까와 동시에 유지보수를 쉽게 할 수 있을까? 라는 생각을 했다.
그리고 I/O 속도도 빠르면 좋다고 생각했다
1. BufferedReader 와 BufferedWriter 를 사용하자
2. StringTokenizer 로 문자열을 분해하자
3. 유지보수를 쉽게하기 위해 점수를 전역변수로 관리하자
4. 코드 라인이 짧아지는게 가능하겠다.

해답

1. 각 종족의 점수 * 종족의 수 = 점수
2. 점수 비교 점수
3. 출력

문제

중간계에 전쟁이 일어나려고 한다. 간달프는 사우론에 대항하기 위한 군대를 소집했고, 여러 종족이 이 군대에 가담했다. 전쟁을 시작하기 전에 간달프는 각 종족에 점수를 매겼다.

간달프의 군대의 각 종족의 점수는 다음과 같다.

  • 호빗 - 1
  • 인간 - 2
  • 엘프 - 3
  • 드워프 - 3
  • 독수리 - 4
  • 마법사 - 10

사우론의 군대의 점수는 다음과 같다.

  • 오크 - 1
  • 인간 - 2
  • 워그(늑대) - 2
  • 고블린 - 2
  • 우럭하이 - 3
  • 트롤 - 5
  • 마법사 - 10

중간계는 매우 신비한 곳이어서 각 전투의 승리는 날씨, 장소, 용맹에 영향을 받지 않는다. 전투에 참여한 각 종족의 점수를 합한 뒤, 큰 쪽이 이긴다.

전투에 참여한 종족의 수가 주어졌을 때, 어느 쪽이 이기는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 전투의 개수 T가 주어진다. 각 전투는 두 줄로 이루어져 있다. 첫째 줄에 간달프 군대에 참여한 종족의 수가 주어진다. 이 값은 공백으로 구분되어 있으며, 호빗, 인간, 엘프, 드워프, 독수리, 마법사 순서이다. 둘째 줄에는 사우론 군대에 참여한 종족의 수가 주어진다. 이 값 역시 공백으로 구분되어 있으며, 오크, 인간, 워그, 고블린, 우럭하이, 트롤, 마법사 순서이다. 모든 값은 음이 아닌 정수이고, 각 군대의 점수의 합은 32비트 정수 제한을 넘지 않는다.

출력

각 전투에 대해서, "Battle"과 전투 번호를 출력한다. 그 다음에 간달프의 군대가 이긴다면 "Good triumphs over Evil"를, 사우론의 군대가 이긴다면 "Evil eradicates all trace of Good", 점수의 합이 같아 이기는 쪽이 없다면 "No victor on this battle field"를 출력한다.

예제 입력 1 

3
1 1 1 1 1 1
1 1 1 1 1 1 1
0 0 0 0 0 10
0 1 1 1 1 0 0
1 0 0 0 0 0
1 0 0 0 0 0 0

예제 출력 1 

Battle 1: Evil eradicates all trace of Good
Battle 2: Good triumphs over Evil
Battle 3: No victor on this battle field


1. O(N^3) 인 문제

문제

평면에 색깔이 서로 다른 직사각형 모양의 색종이 N장이 하나씩 차례로 놓여진다. 이 때 색종이가 비스듬하게 놓이는 경우는 없다. 즉, 모든 색종이의 변은 서로 평행하거나, 서로 수직이거나 둘 중 하나이다. 그림-1은 1번, 2번, 3번 세 장의 색종이가 순서대로 놓인 상태를 보여준다.

그림-1

여기에 그림-2에서 보인 것처럼 4번 색종이가 하나 더 놓이면 3번 색종이는 완전히 가려서 보이지 않게 된다. 그리고, 1번 색종이와 2번 색종이는 부분적으로 가려 보이며, 4번 색종이는 완전히 보이게 된다.

그림-2

N장의 색종이가 주어진 위치에 차례로 놓일 경우, 각 색종이가 보이는 부분의 면적을 구하는 프로그램을 작성하시오. 

입력

입력의 첫 번째 줄에는 색종이의 장수를 나타내는 정수 N (1 ≤ N ≤ 100)이 주어진다. 이어서 N장의 색종이에 관한 입력이 각 색종이마다 한 줄씩 차례로 주어진다. 색종이가 놓이는 평면은 가로 최대 101칸, 세로 최대 101칸으로 구성된 격자 모양이다. 격자의 각 칸은 가로, 세로 길이가 1인 면적이 1인 정사각형이다. 

편의상 가로 6칸, 세로 6칸으로 이루어진 격자의 예를 들어 설명하면, 각 칸에 표시된 값 (a,b)는 해당 칸의 번호를 나타낸다. 가장 왼쪽 아래의 칸은 (0,0) 가장 오른 쪽 위의 칸은 (5,5)이다. 

색종이가 놓인 상태는 가장 왼쪽 아래 칸의 번호와 너비, 높이를 나타내는 네 정수로 표현한다. 예를 들어, 위 그림에서 회색으로 표시된 색종이는 (1,4)가 가장 왼쪽 아래에 있고 너비 3, 높이 2이므로 1 4 3 2로 표현한다. 색종이가 격자 경계 밖으로 나가는 경우는 없다. 

출력

입력에서 주어진 순서에 따라 N장의 색종이를 평면에 놓았을 때, 입력에서 주어진 순서대로 각 색종이가 보이는 부분의 면적을 한 줄에 하나씩 하나의 정수로 출력한다. 만약 색종이가 보이지 않는다면 정수 0을 출력한다. 

예제 입력 1 

2
0 0 10 10
2 2 6 6

예제 출력 1 

64
36


1. 예전에 풀었던 이분탐색들이랑 비슷한 문제

2. 문제가 친절해서 0ml 인 경우는 없다.

3. r - 1 을 해줘야 답이 정상적으로 출력된다. (l 이 r 을 같거나 넘어가면서 r - 1 이 최대값이 됨)

문제

프로그래밍 대회 전날, 은상과 친구들은 이상한 술집에 모였다. 이 술집에서 막걸리를 시키면 주전자의 용량은 똑같았으나 안에 들어 있는 막걸리 용량은 랜덤이다.  즉 한 번 주문에 막걸리 용량이 802ml 이기도 1002ml가 나오기도 한다.  은상은 막걸리 N 주전자를 주문하고, 자신을 포함한 친구들 K명에게 막걸리를 똑같은 양으로 나눠주려고 한다.  그런데 은상과 친구들은 다른 주전자의 막걸리가 섞이는 것이 싫어서, 분배 후 주전자에 막걸리가 조금 남아 있다면 그냥 막걸리를 버리기로 한다.  (즉, 한 번 주문한 막걸리에 남은 것을 모아서 친구들에게 다시 주는 경우는 없다.  예를 들어 5명이 3 주전자를 주문하여 1002, 802, 705 ml의 막걸리가 각 주전자에 담겨져 나왔고, 이것을 401ml로 동등하게 나눴을 경우 각각 주전자에서 200ml, 0m, 304ml 만큼은 버린다.) 이럴 때 K명에게 최대한의 많은 양의 막걸리를 분배할 수 있는 용량 ml는 무엇인지 출력해주세요.

입력

첫째 줄에는 은상이가 주문한 막걸리 주전자의 개수 N, 그리고 은상이를 포함한 친구들 K명이 입력된다. N은 10000이하의 정수이고, K는 1,000,000이하의 정수이다. 막걸리의 용량은 231 -1 보다 작거나 같은 자연수이다. (단, 항상 N ≤ K 이다. 즉, 주전자의 개수가 사람 수보다 많을 수는 없다 ) .

출력

첫째 줄에 K명에게 나눠줄 수 있는 최대의 막걸리 용량 ml 를 출력한다.

예제 입력 1 

2 3
702
429

예제 출력 1 

351

예제 입력 2 

4 11
427
541
774
822

예제 출력 2 

205

힌트

2번째 예제에서 205ml로 나눌 경우 2,2,3,4 가 된다. 하지만 206ml라고 하면 각각 2, 2, 2, 3 으로 나눌 수 있기 때문에 나누는 용량을 조금 줄여야한다.


1. 숫자를 입력받고 정렬해서 출력하면 된다.

2. 우선순위 큐를 사용했는데, 통과했다.

3. 원래 생각하던 솔루션은 입력받고 mergesort (quicksort 는 stack 메모리 초과될걸로 예상)

문제

정렬되어있는 두 배열 A와 B가 주어진다. 두 배열을 합친 다음 정렬해서 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 배열 A의 크기 N, 배열 B의 크기 M이 주어진다. (1 ≤ N, M ≤ 1,000,000)

둘째 줄에는 배열 A의 내용이, 셋째 줄에는 배열 B의 내용이 주어진다. 배열에 들어있는 수는 절대값이 109보다 작거나 같은 정수이다.

출력

첫째 줄에 두 배열을 합친 후 정렬한 결과를 출력한다.

예제 입력 1 

2 2
3 5
2 9

예제 출력 1 

2 3 5 9

예제 입력 2 

2 1
4 7
1

예제 출력 2 

1 4 7

예제 입력 3 

4 3
2 3 5 9
1 4 7

예제 출력 3 

1 2 3 4 5 7 9

출처


1. 이번에는 홍대 문제를 풀어봐야겠다.

2. 간단한 구현 문제인데 풀고 난 후 깔끔한 솔루션이 생각났다.

3. 배열에 스왑되는 idx 를 미리 적어놓고 스왑하는 코드는 따로 빼놓으면, 유지보수가 하기 쉬워진다.

문제

야바위를 잘하는 재열이는 축제기간동안 홍문관 앞에 부스를 열어 돈을 벌어보려 한다. 

재열이는 컵 네 개를 일렬로 탁자 위에 올려놓고, 가장 왼쪽 컵에 작은 공 하나, 가장 오른쪽 컵에 큰 공 하나를 넣어놓았다. 이제 재열이는 컵 2개의 위치를 바꿔가면서 여러번 섞을 것이고, 모두 섞은 뒤에 상대방에게 어떤 컵에 공이 들어있는지 말하라고 할 것이다. 컵이 4개가 있을 때, 위치를 바꿀 수 있는 가능한 방법은 아래와 같이 6가지가 있다.

떼돈을 벌기 위해 3개월을 연습한 재열이에게 내기를 이길 수 있는 사람은 거의 없다.  그러나, 마침 엄청난 동체시력의 보유자 영범이 홍문관 앞을 지나고 있었다.  영범은 내기를 제안하고, 아무것도 모르는 재열이는 말없이 컵을 섞기 시작한다.  재열이의 손놀림이 아무리 빠르더라도, 영범이의 동체시력을 속일 수는 없다. 영범이는 동체시력뿐만 아니라, 기억력도 뛰어나서 재열이가 컵을 섞은 순서를 다 기억할 수 있다.  이것을 모르는 재열이의 운명은 당신이 작성할 프로그램에 달려있다.

재열이가 컵을 섞은 방법이 순서대로 주어질 때, 어떤 컵에 작은 공이 있는지, 어떤 컵에 큰 공이 있는지 차례대로 출력하는 프로그램을 작성하시오. 

입력

첫째 줄에 재열이가 컵을 섞는 순서가 주어진다. 이 순서는 위 그림에 있는 A, B, C, D, E, F 중 하나이다. 재열이는 컵을 최대 200번 섞는다.

출력

첫번째 줄에는 작은 공이 있는 위치를, 두번째 줄에는 큰 공이 있는 위치를 출력한다. 공의 위치는 가장 왼쪽부터 1, 2, 3, 4로 표시한다.  

예제 입력 1 

AB

예제 출력 1 

2
4


1. 좌, 우로만 이동 가능

2. K = 0 인 경우가 있어서 split 할 때 에러가 난다. (try catch 로 해결)

3. 모든 경우를 다 확인한다고 했을 때, O(N)

문제

홍익대학교 근처에 있는 오락실에 새로운 게임이 들어왔다. 이 게임을 클리어하려면 방금 막 금은방을 턴 마포구 대도 X가 되어 아무에게도 들키지 않고 X의 집에 무사히 도착해야 한다. 게임은 오직 좌우 버튼 두 개로만 진행되고 규칙은 아래와 같다.

  1. 마포구의 모든 건물은 일렬로 나열되어 있고 각 건물에는 1번부터 N번까지 번호가 지정되어 있다. 마포구에는 K개의 경찰서가 있고 경찰 내부에는 이미 X의 얼굴이 알려졌다.
  2. 게임이 시작될 때 X는 막 범행을 끝내고 금은방 S에 있다.
  3. X는 자신의 집 D에 마포구를 떠날 수 있는 비밀 통로를 만들어놓았다. 따라서 경찰에게 발각되지 않고 무사히 집으로 돌아가야 한다.
  4. 좌(←) 버튼을 누르면 후방으로, 우(→) 버튼을 누르면 전방으로 이동한다. X는 마포구 내에서만 이동할 수 있으며, 자신이 오랜 연구 끝에 알아낸 이동 방식을 맹신하여 오직 그 방식으로만 이동한다.
  5. X의 달리기는 매우 빨라서 전방으로 F개의 건물, 후방으로 B개의 건물을 얼굴이 보이지 않는 빠르기로 달릴 수 있다. 하지만 자신도 주체할 수 없을 만큼 빨라서 중간에 멈출 수 없으며, 한 번 달리면 너무 힘들어 10초 동안 건물 앞에서 휴식을 취해야 한다.
  6. X가 경찰서 앞에서 휴식을 취할 경우 그는 집에 돌아가지 못하고 체포된다.

이 게임은 아직 베타 버전이라 무사히 집으로 가는 방법이 없는 버그도 존재한다.

지언이의 취미는 오락실 게임을 누구보다 빠르게 클리어하는 것이다. 그래서 대도 X가 무사히 집에 도착할 수 있는 여러 방법 중에서도 좌우 버튼을 가장 최소로 눌렀을 때의 횟수를 알고 싶다.

마포구 건물의 개수 N, 털린 금은방 S, 빈집털이범의 집 D, 앞으로 한 번에 달릴 수 있는 건물 수 F, 뒤로 한 번에 달릴 수 있는 건물 수 B, 마포구 경찰서의 개수 K, 각 경찰서의 건물 번호 l1, l2, …, lK가 주어질 때 대도 X가 무사히 집에 도착하기 위해 버튼을 눌러야 하는 최소 횟수를 출력하는 프로그램을 작성해라.

만약 집으로 가는 방법이 없는 경우를 발견했다면 이 데이터를 게임 회사에 알리기 위해 “BUG FOUND”를 출력한다.

입력

첫째 줄에 N, S, D, F, B, K가 주어지고, K > 0인 경우에는 둘째 줄에 경찰서의 위치 l1, l2, …, lK가 주어진다. (1 ≤ S, D, k ≤ N ≤ 100000, 0 ≤ F, B ≤ 100000, 0 ≤ K ≤ N/2, S ≠ D ≠ l) 

출력

첫째 줄에 대도 X가 건물 S에서 자신의 집 D로 무사히 가기 위해 지언이가 버튼을 눌러야 하는 최소 횟수를 출력한다. 만약, D에 도달할 수 없는 데이터인 경우 “BUG FOUND”를 출력한다.

예제 입력 1 

20 1 20 2 1 4
5 10 15 19

예제 출력 1 

14

예제 입력 2 

20 1 20 2 1 3
5 6 9

예제 출력 2 

BUG FOUND


1. 메모리 제한이 8MB 인 문제

2. 자바는 boolean 배열을 사용해도 되지만, 다른 언어는 되지 않는다.

3. 자바에서 제공하는 BitSet 이라는것을 사용하지 않을 시, int 배열을 만들어서 쪼개고 쪼개고 넣으면 될 것 같다.

문제

문제: N개의 정수 A1, A2, ..., AN 을 읽고, 이들 중에서 반복되는 수를 제외하고 남은 N'개의 수 B1, B2, ..., BN’ 을 입력된 순서대로 출력하시오. 이때,

  1.  Ai < 225 = 33554432, i=1,2,…,N.
  2. 입력의 갯수 N은 1 이상 500만 이하이다.

입력

첫째 줄에 A1, A2, ..., AN이 주어진다.

출력

B1, B2, ..., BN’을 출력한다.

예제 입력 1 

12 1 449 12 555 1201 912 555 19372

예제 출력 1 

12 1 449 555 1201 912 19372

예제 입력 2 

21003957 20891590 11382885 18340118 11354168 5461061 12693617 2552341 14639514 25224366 19239852 136782 17206566 18675414 9536557 24961835 2507460 32083310 4485200 19506627 21087117 9270314 12953612 10216350 8170712 20436397 11382885 29305594 27169105

예제 출력 2 

21003957 20891590 11382885 18340118 11354168 5461061 12693617 2552341 14639514 25224366 19239852 136782 17206566 18675414 9536557 24961835 2507460 32083310 4485200 19506627 21087117 9270314 12953612 10216350 8170712 20436397 29305594 27169105

힌트

메모리 제한에 유의하시오.


1. 입출력을 더 빠르게 처리하는 기술을 알아야 시간 단축에 도움이 될 것 같다.

2. O(NlgN)

문제

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.

예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {1020, 10, 30, 20, 50} 이고, 길이는 4이다.

입력

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.

둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000)

출력

첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.

예제 입력 1 

6
10 20 10 30 20 50

예제 출력 1 

4

출처



    1. LIS

    2. O(NlgN)

    문제

    수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.

    예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {1020, 10, 30, 20, 50} 이고, 길이는 4이다.

    입력

    첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.

    둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (-1,000,000,000 ≤ Ai ≤ 1,000,000,000)

    출력

    첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.

    예제 입력 1 

    6
    10 20 10 30 20 50
    

    예제 출력 1 

    4
    

    출처


    + Recent posts