일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- JP-Q30
- NM-LA03
- 라이트닝 젠더
- FILCO
- 프로세서 연결하기
- 이거샀음
- Code Jam 2019
- cmpt-prog
- Full Search
- 샤오미
- 마제스터치 컨버터블2
- Netmate
- 퀵차지3.0
- 바이퍼럭스
- 클레버 타키온
- j7-c
- git-merge
- 보조배터리
- QC3.0
- PLM02ZM
- PLM05ZM
- 미 파워뱅크
- USB 테스터기
- Google My Maps
- 유무선 키보드
- Dat Bae
- MFI
- 블루윈
- SWEA
- Code Jam
- Today
- Total
이륙하라
Code Jam 2019 Qualification Round "Dat Bae" 본문
Dat Bae 문제의 풀이를 우연히 떠올리게 되어 F=5
테스트케이스도 맞췄는데 구글에서 제시한 풀이는 내 것과 사뭇 달랐다.
내 풀이는 딱 B<=16
인 경우에만 적용되지만 구글이 제시한 풀이는 B<32
도 된다!
내 풀이
첫번째 쿼리로 비트열을 구획화 한다. 이 구획화로 얻으려는 결과물은 보낸 비트열의 특정 구획이 받은 비트열의 어떤 구획과 대응되는지 알아내는 것이다. 이 정보를 토대로 그 구획에 해당되는 컴퓨터들 중 고장낸 것들의 "개수"를 알아낼 수 있다. (아직 어떤 컴퓨터인지는 모른다.)
000....00
을 보내면 어떻게 될까? 0
의 개수만 줄어들은 0000....00
이 돌아온다. 이런 식으로 보내면 아무런 정보를 얻을 수 없다.
그래서 착안한 방법은 같은 개수의 연속된 0
과 1
이 번갈아가며 나타나는 비트열을 보내는 것이다. (ex 000111000111...
) 0과 1로 구획 경계를 만드는 것이다. 이렇게 보내면 수신한 비트열도 0
과 1
이 번갈아가며 나타날텐데 다른 점은 고장난 컴퓨터들로 인해 구획별로 비트의 개수에 차이가 난다.그렇다면 이 개수를 새면 위에서 얘기한 구획별 고장난 컴퓨터들의 개수를 알아낼 수 있다.
그런데 고려해야할 엣지케이스가 있다.
000111000111000111
을 보냈는데 두번째 000111
에 해당하는 컴퓨터들이 죄다 고장났다면 000111000111
이 돌아올텐데 첫번째나 세번째 000111
을 삭제시켜도 같은 비트열을 만들어낸다. 모호성: 고장난 컴퓨터들의 위치를 확정지을 수 없다.
위의 문제는 단위 구획의 크기를 늘려서 해결 할 수 있다. B=6
이라면 구획의 크기를 6으로 주면 된다. (000000111111...
) 만약 고장난 컴퓨터 6개의 위치들이 111111
라면 000000000000
같은 패턴이 나타날텐데 구획의 크기는 6이므로 고장난 컴퓨터는 저 12개의 0비트의 한가운데임을 쉽게 알 수 있고 만약 앞선 예시같이 몰려있지 않다면 구획에 적어도 1개 이상의 비트가 살아남아 수신되므로 구획별 고장난 컴퓨터의 개수를 알 수 있다.
구획별 고장난 컴퓨터의 개수를 알아냈다. 원래의 problem의 여러 개의 subproblem으로 쪼개졌다. 각 subproblem은 보내는 비트열의 길이가 B
이다. 보낸 비트열의 개수가 B/2
, B/4
, ... 인 subproblem들로 쭉쭉 내려간다.
종국에는 보내는 비트열이 01
이 될 것이고 고장난 컴퓨터의 위치를 확정지을 수 있다.
왜 내 풀이가 B<=16
일 때만 적용되나? 첫번째 구획화를 할 때 1회 쿼리, 그 다음 subproblem으로 쪼갤 때 할 수 있는 쿼리의 최대 횟수는 4회이다. 이 4회만에 크기가 1인 subproblem에 도달해야 한다. 그래서 2^4=16
인 것이다.
(edit) 다시 분석해보니 내 풀이도 16<B<32 인 경우에도 적용할 수 있다는 것을 알아냈다. 01
이 가장 마지막으로 전송하는 비트열의 패턴이므로 F=5면 처음에 00000000000000001111111111111111
(총 길이 32)을 보낼 수 있다.
구글의 풀이
내 풀이가 모범답안이라 확신하고 채점이 끝난 뒤 올라온 구글의 풀이를 봤더니 우와소리가 나오는 방법을 썼다!
구글은 F번의 쿼리를 보내면 각 컴퓨터를 F개의 비트열로 특정할 수 있음에 착안했다. (이 부분을 처음 읽을 때 소름이 돋았다)
첫번째 테스트케이스의 경우에는 1024개의 컴퓨터를 F=10 번의 쿼리를 보내 각 컴퓨터별로 유일한 비트열(값으로 따지면 0 ~ 1023이다)을 부여한 다음 수신 받은 비트열로 재구성을 했을 때 존재하지 않는 비트열들에 해당되는 컴퓨터가 고장났음을 알아냈다.
두번째 테스트케이스는 5번의 쿼리만이 주어진다. 이젠 0 ~ 31 밖에 부여하지 못한다. 이번 풀이는 내 풀이 중 구획화와 비슷한 부분이 있다. 1024개의 컴퓨터에 0, 1, ..., 31, 0, 1, ..., 31, ..., 0, 1, ..., 31 을 부여한다. 여기서 최대 31개의 연속된 위치의 컴퓨터가 죽어도 어떤 구획의 마지막 정상 컴퓨터의 번호은 그 다음 구획의 첫 정상 컴퓨터의 번호보다 항상 크거나 같다. 당장 1, 2, 3, ..., 31 을 고장내봐도 0, 0, 1, ..., 31 으로 첫번째 0과 두번째 0 사이에서 구획이 달라짐을 알 수 있다. 연속된 32개가 죽는 경우는 처리할 수 없다. (내 풀이에서 언급한 모호성이 있다)
'WA! PS!' 카테고리의 다른 글
BOJ-11975 Build Gates (1) | 2019.08.04 |
---|---|
SW Expert Academy 5648 "원자 소멸 시뮬레이션" (0) | 2019.04.12 |
SW Expert Academy 1767 "프로세서 연결하기" (0) | 2019.04.12 |