백준 9

벡터 size()를 함부로 사용하지 말아야 하는 경우

백준 문제를 풀 때 최대 입력값을 사용해서 벡터의 생성과 동시에 크기를 할당해주는 경우가 있다. vector cards(100); 이런 식으로 생성하면 cards 벡터는 사이즈가 100이 된다. 그런데 코드를 짜는 중간에 cards.size()를 사용했다? 그렇다면 당신은 찾기 어려운 오류 속으로 빠져들었다. (초보이면 화가 솟구치는 자신을 발견하게 된다) 입력받는 테스트 케이스에서 card의 갯수가 5개나 8개로 주어질 수 있다. for (int i = next; i < cards.size(); i++) 이런 반복문을 짜게 된다면? 있지도 않은 카드 값으로 반복문을 돌리고 있게 된다. 그리고 당연히 예상한 시간보다 계산이 훨씬 더 오래 걸린다. 당근 답도 이상한 답이 나온다. 결론 1. 벡터 생성과 동..

인덱스를 통한 배열 접근 시 항상 조심하자

백준 1697번을 풀다 발견한 논리 오류다. 종종 발생할 수 있는 문제라 여겨 기록을 해둔다. 처음에는 이렇게 코드를 작성했다. 논리적으로는 알고리즘이 문제가 없어보이는데 계속 런타임 오류가 났다. #include #include #define MAX 100000 using namespace std; int S, D; int dx[3] = { 1,-1,2 }; bool visited[MAX] = { 0, }; queue q; void bfs() { int x=S, nx, level=0; q.push(x); visited[x]= true; while (!q.empty()) { int q_size = q.size(); while (q_size--) { x = q.front(); q.pop(); if (x =..

[c++]std::list::erase() 함수 사용 시 반환 값을 사용하자

c++에 정의되어 있는 보통의 컨테이너와 마찬가지로 std::list 역시 end()는 마지막 노드 다음을 가리키고 있다. list는 이터레이터 증가/감소가 1씩만 가능하고 임의의 원소에 바로 접근하는 건 불가능하다. 그리고 좋은 점은 벡터와 달리 이터레이터를 이용해 erase 해도 이터레이터를 계속 사용 가능하다. 중간에 원소 삽입/삭제 또한 O(1) 시간복잡도면 가능하다. 중간의 원소를 가리키는 이터레이터를 이용해서 erase(itr); 이렇게 코드를 사용했다고 해보자. 그리고 erase() 함수의 리턴값을 사용하지 않았다고 치자. 이터레이터가 가리키고 있던 노드가 삭제되었다. 힙 영역의 어느 한 곳의 주소값을 가지고 있었는데 그 주소값은 존재하지 않는 값이 되었다. 그러니 itr-- / itr++ ..

예제 입출력은 분명 맞는데 틀렸다고 할때 대처법

백준 문제를 풀다보면 예제 입력을 여러개 넣어봤고 출력도 홈페이지에 나와있는 거랑 똑같은데 막상 채점을 해보면 "틀렸습니다"라는 잔인한 글씨를 보여주는 경우가 있다. 아마 문제를 보면 N Microsoft c + + 32 비트 및 64 비트 컴파일러는이 문서의 뒷부분에 나오는 표의 유형을 인식 합니다.The Microsoft C++ 32-bit and 64-bit compilers recognize the types docs.microsoft.com int는 약 20억인데 이걸 넘는 경우가 꽤 자주 있다. 그러니 이럴 경우에는 안전하게 가장 범위가 큰 자료형을 사용하자. 그것은 long long~ 억조를 넘어 경까지 품을 수 있을 정도로 범위가 크다.

배열을 fill()로 초기화해주자.

전역변수에 배열을 선언하면 알고리즘 문제를 풀 때 편한 건 분명하다. 어느 함수에서든 배열을 가져다 쓸 수 있기 때문이다. 그런데 이걸 도입하고서 초반부에 디버깅에 어려움을 겪게 한 일이 있다. main 위에 int arr[101] = {-1}; 이렇게 코드를 작성했다. 이렇게 하면 당연히 모든 값이 -1로 초기화될 줄 알았다. 그런데 계속 이상한 값이 출력돼서 디버깅 해보니 배열의 첫 원소만 -1이고 나머지는 모두 0이었다. 그래서 프로그램이 의도치 않게 작동했다. 결론 배열의 모든 값들을 0으로 초기화하려 한다면 ={0,}으로도 가능하다. 배열의 모든 값들을 0이 아닌 다른 값들로 초기화하고자 하면 에 있는 std::fill()을 사용해 배열의 값들을 초기화하자.

백준 11720번 숫자의 합(문자로 안 받고 정수로 받기)

백준 11720번 문제를 풀고서 남들은 어떻게 풀었나 보기 위해 구글에 검색을 해봤다. 그런데 상위 글들 전부 문자로 받아서 '0' 아스키 코드와의 차이를 이용한 풀이였다. 그래서 이런 방법도 가능하다는 걸 기록에 남기고자 한다. 그냥 정수로 받을 수 있다. 단 1자리씩 받는 것이다. scanf("%1d", &num); 이런 식으로 %d 사이에 1을 끼워줌으로서 1개만 받겠다고 컴퓨터에게 말해주는 것이다. 전체 코드는 이렇다. #include using namespace std; int main() { int num; int n; scanf("%d", &n); int sum = 0; for (int i = 0; i < n; i++) { scanf("%1d", &num); sum += num; } prin..

[c++]리스트 sort 하는 방법

C++ #include #include int main() { std::list lst; lst.push_back(5); lst.push_back(1); std::sort(lst.begin(), lst.end()); return 0; } 당연하다는 듯이 이런 코드를 작성한 적이 있는데 sort 부분에서 에러가 뜬다. 이유는 아래와 같다. template void sort( RandomIt first, RandomIt last ); RandomIt must meet the requirements of ValueSwappable and LegacyRandomAccessIterator. std::sort 함수의 매개변수로 오는 반복자는 반드시 RandomAccessIterator 타입이어야 한다. 벡터는 반복..

cin과 scanf는 공백 문자를 어떻게 인식하는가

백준 알고리즘 문제를 풀 때 고민을 많이 하게 된다. 기본 입출력부터 고민거리가 생긴다. 그래서 c++에서 사용하는 입력함수 cin과 scanf를 비교해봤다. //편의상 delete문 제외 cin 테스트 #include #include using namespace std; int main() { int n; scanf("%d", &n); char** board = new char* [n]; for (int i = 0; i > board[i][j]; } } cout > 뒤에 오는 변수에 저장한다고 나와있다. 자 처음에 2->..