사실상 이 포스트를 작성한 실질적인 이유인데, std::string c_str()함수를 사용하면 string형이 char *형으로 변환된다. 이를 활용하면 기존에 string타입에서는 사용할 수 없었던 strtok, strlen 등 string.h에 포함되어있는 여러 함수들을 사용할 수 있게된다.
이해를 못한 부분은 1-2. 위에서 자른 막대의 절반 중 하나를 버리고 남아있는 막대의 길이의 합이 X보다 크거나 같다면, 위에서 자른 막대의 절반 중 하나를 버린다. 이 부분인데 처음 64에서 절반 중 하나를 버리고 나머지 하나를 버리면 0인데 뭐 어쩌라는 거지라는 생각을 계속 했다. 이 부분 때문에 구글링도 했는데 나랑 비슷한 사람이 은근 있더라... 어쨌든 저 부분을 풀어서 설명하자면 위에서 자른 절반의 막대와 그 외의 나머지 막대의 길이의 합이 X보다 작으면 절반의 막대 두 개를 그대로 챙기고, 크거나 같다면 둘 중 하나를 버린다는 뜻이다. 즉, 막대의 길이의 합이 X보다 작다면 자르기만 하고 둘 다 챙긴다는 뜻이다.
2. 또 다른 풀이
문제를 풀고난 이후 태그를 봤는데 비트마스킹을 봤다. 그래서 왜 이 문제가 비트마스킹인가? 에 대해서 생각해봤다. 이 문제는 기본 막대기의 크기가 64(1000000==26)으로 주어져있다. 그리고 항상 2씩 나누면서 버릴지 유지할지를 결정한다.
괄호를 적절히 넣는다는 말은 그냥 계산 우선순위를 만들라는 것이고 가장 작은 수를 만들기 위해서는 숫자와 -사이에 괄호가 있다면 수가 -가 되어서 가장 작은 수가 될 것이다.
이 예제를 보면 결국
55−(50+40)
이러한 식이 되어 결과값이 35가 나오게 된다.
이는 이후 +가 나오면 위 식과 같이 한번에 -를 하게되고 만약 -가 나온다면 한 번 괄호를 닫았다가 다시 괄호를 열게된다. 즉, 이후 어떠한 연산자가 나오든지 상관없이 쭉 -연산만 진행해주면 된다. 따라서 minus에 관한 bool타입 변수를 만들어서 이를 확인하면 될 것 같다.
이렇게 예쁜 이진탐색코드를 작성했더니 틀렸다고 나온다. 이때부터 맞왜틀을 계속 외치기 시작한다. 분명 예제도 정상적으로 작동하고 다른거 이상한거 넣어도 정상적으로 작동하는데 왜 안되지?
그때부터 눈이 돌아가서 하나씩 바꿔보기 시작하다가 어쩌다 반례를 찾았다.
원래라면 결과값이 0이 나와야 하지만 1이 나와버렸다. 반례를 찾았으니 이것을 해결하기 위해 열심히 디버거를 돌려봤는데,
배열에서 우리가 입력을 하고 사용하는 크기는 1이다. 즉, 인덱스는 0까지만 사용한다. 그러나 두번째 bst함수를 들어갔을 때 start와 end가 1이 되고 이에 따라 mid값도 1이 된다. 여기서 arr[1]을 불러왔을 때 이 값이 0이 나오고 그게 target과 같은 수라서 최종 결과로 1이 출력되는 것이다.
이 결과가 결국엔 사용가능한 index를 넘어가서 이러한 결과가 나온다고 생각해서 bst함수에 함수의 크기 len이라는 인자를 추가해주고 처음 탈출 조건에 start > len이라는 조건을 추가해줬다.
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100000
intcompare(constvoid *a, constvoid *b);
intbst(int* arr, int start, int end, int target, int len);
intmain(){
int n, m;
int t, temp;
int* arr;
scanf("%d", &n);
arr = malloc(sizeof(int) * n);
for(int i = 0; i < n; i++)
scanf("%d", &arr[i]);
qsort(arr, n, sizeof(int), compare);
scanf("%d", &m);
for(int i = 0; i < m; i++) {
scanf("%d", &temp);
if(bst(arr, 0, n, temp, n) != -1) printf("1\n");
elseprintf("0\n");
}
return0;
}
intcompare(constvoid *a, constvoid *b){
if(*(int *)a > *(int *)b) return1;
elseif(*(int *)a < *(int *)b) return-1;
elsereturn0;
}
intbst(int* arr, int start, int end, int target, int len){