6개의 댓글이 있습니다.
-
-
Being -
위에서 설명한 대로 예를 들어 싸이클의 길이가 N이라고 하면
1/2 1/4 1/8 .. 1/(2N) 이런 조각들을 분배하면 되는 걸텐데요
그 조각들의 상대적인 크기 비율이 2N-1, 2N-2, ..., 1 이렇구요. 그리고 저 조각들에 대한 분모는 2N - 1일거구요.
위에서 설명한 대로 분모 분자를 적당히 곱해서 분모를 2N - 1꼴로 만들었다고 하면
10진수 무한소수를 표기할 때에 73/99 = 0.737373737373 이렇게 되는 것처럼
2진수 무한소수를 표기할 때에 분모가 (2N - 1)이라면 0.이렇게 나가겠죠. 이렇게 되면 pattern을 구할 때에 굳이 적당히 곱해서 2N - 1 꼴로 만들 필요 없이 그냥 나눗셈을 해도 똑같은 결론을 얻을 수 있으니까요..ㅎㅎ
18년 전 link
-
-
정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.

astein
안녕하세요. Astein입니다.
오랜만에 에디토리얼을 쓰는거라 익숙하지가 않네요 ;ㅁ;
TCO'08 Round 3는 3월 2일 새벽 3시에 열렸습니다. 늦은 시간에도 #icpc 채널에서 응원해 주셨던 많은 분들께 감사의 말씀을..
(그리고..... 지못미 JM ㅜㅜ)
간단히 결과만 쓰면 Astein 7등, ryuwonha 9등, lewha0 52등, ainu7 114등으로 이렇게 네 명이 Round 4에 진출하게 되었습니다.
Easy (250 pts.)
* 문제 설명
당신은 친구와 케이크를 나누어 먹으려고 합니다. 만약 전체 케익의 절반을 당신이 먹고, 남은 양의 절반은 친구가 먹는다고 합시다. 이러한 과정을 반복한다면 당신이 먹는 양을 계산할 수 있습니다.
You Him
1/2 + 1/4 +
1/8 + 1/16 +
1/32 + 1/64 +
1/128 + 1/256 +
...
위의 과정을 반복하면 당신은 전체 케이크의 2/3만큼을, 당신의 친구는 1/3만큼을 먹게 됩니다.
하지만 위의 패턴이 아니라 다른 패턴으로 먹을 수도 있고, 다른 패턴으로 먹게 된다면 먹을 수 있는 비율이 달라지게 됩니다. "you, him, you"의 패턴으로 케이크를 분할한다면 당신은 전체 케이크의 5/7만큼을, 당신의 친구는 2/7만큼을 먹게 되니까요.
You Him You
1/2 + 1/4 + 1/8 +
1/16 + 1/32 + 1/64 +
...
첫번째 열과 세번째 열의 값의 합은 두번째 열의 값의 5/2배가 됩니다. 따라서 당신이 먹은 양은 친구가 먹은 양의 5/2배가 되기 때문에 위에서 계산한 결과만큼 먹게 되는 것이죠.
어떤 분수 a/b가 주어졌을 때 제일 간단한 패턴을 찾는 프로그램을 작성하는 것이 문제입니다. "You" 패턴은
*로, "Him" 패턴은-로 표시합니다. 만약 길이 60이하의 패턴으로 만드는 것이 불가능하다면impossible을 리턴하면 됩니다. a와 b는 263-1 이하의 수이고, 서로소입니다.[spoiler="더 보기..."]
* 문제 해법
패턴의 길이가 k라고 가정을 해 봅시다. 첫 번째에 가져가는 사람은 1/2만큼을 가져가고 두 번째에 가져가는 사람은 1/4만큼을 가져가고 ... k번째에 가져가는 사람은 1/(2k)만큼을 가져갑니다. 거꾸로 생각을 해 보면 k번째에 가져가는 사람이 1만큼 가져간다고 했을 때, k-1번째에 가져가는 사람은 (상대적으로) 2만큼 가져가고, k-2번째 가져가는 사람은 4만큼, ..., 첫번째에 가져가는 사람은 2k-1만큼을 가져가게 됩니다.
이를 분수로 나타내면 분모는 (2k) - 1이 되지요. 즉 기약분수 a/b에서 b가 (2k) - 1의 약수라면, 길이 k인 패턴으로 표현할 수 있다는 것이 됩니다.
입력받은 수 a/b를 분모가 (2k) - 1인 꼴에 맞도록 일정한 수를 곱해줍니다. 그러면 a' / (2k - 1) 꼴의 분수를 찾을 수 있지요. 여기서 a'을 이진수로 바꿔서 매핑하면 답을 구할 수 있습니다. 마지막자리는 1, 그 앞자리는 2, ..., 의 식으로 표현되어 있기 때문이지요.
저는 처음에 길이가 60 이상인 경우 impossible이라는 말을 확인하지 못해서 resubmit을 하게 되었네요. 덕분에 챌린지도 3개나 성공하긴 했지만요. :) 만약 문제를 풀다가 resubmit한 경우라면 다른 사람도 같은 실수를 할 수 있다고 생각하고 챌린지 페이즈때 미리 준비하는 것도 하나의 팁이 될 수 있겠네요.
~~~ cpp
long long a, b;
struct ZenoDivision {
string cycle(string _a, string _b) {
sscanf(_a.c_str(), "%Ld", &a);
sscanf(_b.c_str(), "%Ld", &b);
long long up, down = 0;
for (int i = 0; i < 63; ++i) {
down = down + down + 1;
if (down % b == 0) {
up = (down / b) * a;
string S = "";
for (int j = 0; j < i + 1; ++j) {
if (up & (1LL << j)) S = '*' + S; else S = '-' + S;
}
if (S.size() > 60) break;
return S;
}
}
return "impossible";
}
};
Hard (1000 pts.)
* 문제 설명
18년 전