티스토리 뷰

언타이틀/코드리뷰

비밀 번호 @507

박은우_ethan 2016. 6. 1. 14:34


#include <iostream>
using namespace std;
//박은우
void two(long long int t, long long int &high, long long int &low);
 
int main() {
    long long int a;
    long long int high, low;
    high = low = 0;
    cin >> a;
    two(a, high, low);
    cout << low << " " << high;
    return 0;
}
 
void two(long long int a, long long int &high, long long int &low) {
    long long int t = a;
    long long int zero = 1;
    long long int one = 0;
    long long int underL = 0;
    long long int underH = 0;
    bool h = false;
    bool l = false;
    long long int length = 1;
    int num = 0;
 
    while (t)
    {
        if (t % 2) {
            num++;
            if (low == 0) {
                underL += length;
            }
            if (high == 0) {
                underH += length;
            }
            h = false;
            l = false;
        }
        else {
            if (high == 0) {
                h = true;
            }
            l = true;
        }
 
        if (h && num != 0) {
            zero /= 2;
            high = a + zero - underH + length / 2;
            long long int p = 1;
            for (int i = 0; i < num - 1; i++) {
                p *= 2;
            }
            high += p - 1;
            h = false;
            zero *= 2;
        }
 
        if (l) {
            one = zero;
        }
        else if (one != 0 && low == 0) {
            low = a - one - underL + length;
            for (int i = 0; i < num - 1; i++) {
                low += one /= 2;
            }
        }
 
        zero *= 2;
        t /= 2;
        length *= 2;
    }
    if (high == 0) {
        long long int p = 1;
        for (int i = 0; i < num-1; i++) {
            p *= 2;
        }
        high = length + p - 1;
    }
}


<원리>

입력 받은 수를 2진수로 고칩니다.

1)큰 수 찾기

고친 수를 오른쪽부터 01 이라는 배치가 되어있는 부분을 찾습니다.

ex) 101011100 이면 101011100

찾은 부분의 배치를 바꿉니다.

ex) 101011100 이면 101101100

바꾼 뒤 오른쪽 부분의 1들을 전부 오른쪽 밀착을 합니다.

ex) 101101100 이면 101100011


만약 01이라는 배치가 없다면

맨 왼쪽 1을 왼쪽으로 1칸 이동합니다(자리수를 증가합니다.)

ex) 111000 이면 1011000

오른쪽에 남은 1들을 전부 오른쪽 밀착을 합니다.

ex) 1011000 이면 1000011


2) 작은 수 찾기

고친 수를 오른쪽부터 10 이라는 배치가 되어있는 부분을 찾습니다.

ex) 10010011 이면 10010011

찾은 부분의 배치를 바꿉니다.

ex) 10010011 이면 10001011

바꾼 뒤 오른쪽 부분의 1들을 전부 왼쪽 밀착을 합니다.

ex) 10001011 이면 10001110


만약 10이라는 배치가 없다면 0출력


댓글
«   2025/01   »
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
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크