ë¬¸ì œ ¶
2005-12-30 14:39:20 Accepted 3.256 436 56031 C++ 100 - The 3n + 1 problem
소ê°� ¶
처ì�Œìœ¼ë¡œ 채ì �로봇ì—�게서 Acceptedë�¼ëŠ” ê°�격ì �ì�¸ 메시지를 안겨준 ë¬¸ì œ.
ì •ë§� 수ë�„ ì—†ì�´ ë§Žì�€ 시ë�„를 했었다. 하지만 너무나ë�„ 꼼꼼하면서ë�„ ìƒ�ê°�ì§€ 못한 테스트 ì¼€ì�´ìФì—� í•ìƒ� ì¢Œì ˆí–ˆë‹¤.
ì •ë§� 수ë�„ ì—†ì�´ ë§Žì�€ 시ë�„를 했었다. 하지만 너무나ë�„ 꼼꼼하면서ë�„ ìƒ�ê°�ì§€ 못한 테스트 ì¼€ì�´ìФì—� í•ìƒ� ì¢Œì ˆí–ˆë‹¤.
ì–´ë ¤ì› ë�˜ ì � ¶
1. ìž…ë ¥ 2개가 범위로 들어가는 ë�° 단순히 첫 번째 ìž…ë ¥ì�´ í�´ 것ì�´ë�¼ëŠ” 추측ì�´ 잘못ë�˜ì—ˆë‹¤. (첫 번째 수가 í�° 경우ë�„ 있었ì�Œ)
2. 비트연산ìž�ì�˜ ìœ„ë ¥ì�˜ 대단함ì�„ ëŠ�꼈다. ì§�홀íŒ�별(& ì—°ì‚°ìž�), 나누기2(right shift 1) - 수행ì†�ë�„ê°€ ì—„ì² í–¥ìƒ�ë�¨.
3. ì•Œê³ ë¦¬ì¦˜ì—� 대한 명확한 파악ì�´ 루프 ë�„는 횟수를 í˜„ì €ížˆ 줄여줌ì�„ ë°°ì› ë‹¤. - 홀수 뒤엔 반드시 ì§�수가 온다.
4. 첫 번째 당했ë�˜ ìž…ë ¥ì�˜ 순서 í�¬ê¸° ë¬¸ì œê°€ ì¶œë ¥ì—�서ë�„ 다시 ë§�ì�½ - 단순히 스왑ì�„ 시켜버림으로ì�¨ ì›�래 ìž…ë ¥ì�´ ë§�가지는 모습ì�„ 보였다.
2. 비트연산ìž�ì�˜ ìœ„ë ¥ì�˜ 대단함ì�„ ëŠ�꼈다. ì§�홀íŒ�별(& ì—°ì‚°ìž�), 나누기2(right shift 1) - 수행ì†�ë�„ê°€ ì—„ì² í–¥ìƒ�ë�¨.
3. ì•Œê³ ë¦¬ì¦˜ì—� 대한 명확한 파악ì�´ 루프 ë�„는 횟수를 í˜„ì €ížˆ 줄여줌ì�„ ë°°ì› ë‹¤. - 홀수 뒤엔 반드시 ì§�수가 온다.
4. 첫 번째 당했ë�˜ ìž…ë ¥ì�˜ 순서 í�¬ê¸° ë¬¸ì œê°€ ì¶œë ¥ì—�서ë�„ 다시 ë§�ì�½ - 단순히 스왑ì�„ 시켜버림으로ì�¨ ì›�래 ìž…ë ¥ì�´ ë§�가지는 모습ì�„ 보였다.
코드 ¶
~cpp
// The 3n + 1 problem
// UVa ID : 100
#include <iostream>
using namespace std;
int cycle_length(int input);
int main()
{
int input1, input2;
while (cin >> input1 >> input2)
{
int i;
int max_count = -1;
int temp = 0;
// ìž…ë ¥ì�˜ 순서가 ì ˆëŒ€ 뒤바뀌면 안ë�œë‹¤!!
cout << input1 << " " << input2 << " ";
// 앞ì—� 들어오는 ìž…ë ¥ì�´ ë’¤ì—� ìž…ë ¥ë³´ë‹¤ ë�” í�´ 경우 (for문 ì—�러 ë°©ì§€)
if (input1 > input2)
{
int swap = input1;
input1 = input2;
input2 = swap;
}
for (i = input1; i <= input2; i++)
{
temp = cycle_length(i); // cycle legnth 찾기
if (temp > max_count)
max_count = temp; // � 수를 max_count로
}
cout << max_count << endl;
}
return 0;
}
// cycle length 구하기
int cycle_length(int input)
{
int argument = input; // ì „ë‹¬ì�¸ìž�로 넘어온 수 ì €ìž¥
int count = 0; // 카운트 변수
while (true)
{
// 종료 조건
if (argument == 1)
{
count++;
break;
}
// LSB가 0�면 �수, 1�면 홀수�다.
if ((argument & 1) == 0)
{
// 나누기 2는 right shift를 한 번 하는 것과 같다.
argument >>= 1;
count++;
}
else
{
// 홀수�면 반드시 다�� �수가 온다.
argument = 3 * argument + 1;
argument >>= 1;
count += 2;
}
}
return count;
}










