티스토리 뷰
#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출력
댓글