bits/stdc++.h 헤더 파일이란?

#include <bits/stdc++.h>

간혹 다른사람들이 C++을 이용하여 알고리즘 문제를 푸는 소스코드를 참조했을 때, 위와 같은 헤더가 나타나는 경우가 있습니다. 이 헤더는 어떤 것이고 어떠한 이유로 사용하는 것일까요?

 

bits/stdc++.h 헤더는 모든 표준 라이브러리가 포함된 헤더입니다. 프로그래밍 대회에서 위 해더를 사용하는 것은 좋은 아이디어 입니다. 문제를 풀 때 마다 #include <iostream> 등등을 작성하는 반복적인 일을 줄여서 시간안배를 도와줍니다. 특히나 문제 푸는 시간이 순위에 결정적인 경우에 더 도움이 될 수 있습니다. 프로그래밍 대회에서는 효율적이고 정확한 알고리즘을 찾는 것이 주가 되어야 하기 때문입니다.

 

하지만 소프트웨어 공학적인 측면에서는 #include 구문을 줄이는 것이 중요합니다. 많은 필요없는 파일들을 #include 하게 된다면, 컴파일 시간과 프로그램 크기가 쓸데없이 길어지고 커지게 됩니다.

 

다음은 bits/stdc++ 헤더의 단점들입니다.

- bits/stdc++.h 헤더는 GNU C++ 라이브러리의 표준 헤더가 아니기 때문에, GCC가 아닌 다른 컴파일러로 빌드를 하려고 한다면 실패합니다.

- 쓸대없는 파일들을 추가시켜서 컴파일 시간이 늘어납니다.

- 표준 C++이 아니기 때문에 이식성이 있지도 않고, 컴파일러 종속적입니다.

 

 

다음은 bits/stdc++ 헤더의 장점들입니다.

- 프로그래밍 대회에서 쓸데없는 시간낭비를 줄여주므로 사용하면 좋습니다.

- 필요한 헤더 파일 include 구문을 작성하는데 시간을 줄여줍니다.

- STL이나 GNU C++의 모든 함수들을 기억할 필요가 없습니다.

 

리눅스 머신에서 해당 헤더파일을 한번 열어봤습니다.

 

// C++ includes used for precompiling -*- C++ -*-

// Copyright (C) 2003-2015 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file stdc++.h
 *  This is an implementation file for a precompiled header.
 */

// 17.4.1.2 Headers

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif

// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
 

헤더파일 길이는 100줄 남짓으로, 헤더치고는 별로 길지 않고, 거의다 쓸만한 헤더파일을 다 넣어버린 내용입니다.

 

 

 

윈도우즈 Visual Studio에서 bits/stdc++.h 헤더 사용하기

그런데 만약 이 헤더파일을 Windows Visual Studio에서 사용을 하고 싶다면 어떻게 하는 게 좋을까요?

 

일단 이 bits/stdc++.h 헤더파일은 비표준이기때문에 개발 등에서 사용하기엔 좋은 방법은 아닙니다.

 

하지만 알고리즘 문제해결 등을 할 것이라면, 일반적인 백준이나 코드포스와 같은 온라인 저지에서는 bits/stdc++.h 헤더를 다 지원하기 때문에, 윈도우에서 알고리즘 문제 풀이용으로 헤더를 사용해 보는 것은 나쁘지 않을 수 있습니다.

 

그러면 간단하게, 윈도우에서 적용되도록 비쥬얼 스튜디오 include 헤더들이 저장되는 디렉토리에 bits라는 폴더를 하나 만들고, 그 폴더 하위에 stdc++.h라는 이름의 파일을 집어넣으면 됩니다.

 

일단 윈도우즈 비쥬얼 스튜디오의 include 파일들이 저장되는 디렉토리를 찾아봅시다.

 

제 컴퓨터의 경우는 다음 경로가 include 디렉토리입니다.

 

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\

 

물론 Visual Studio 버전과, 설치된 드라이브 명에 따라 조금씩 경로는 다를 수 있습니다.

 

이 경로에 bits라는 디렉토리를 하나 만들어 준 뒤, 그 하위 경로에 stdc++.h라는 텍스트 파일을 하나 만들어 줍시다.

 

(아마 해당 경로에는 바로 텍스트 파일을 만들기에는 관리자 권한이 필요할 수 있으므로, 바탕화면 등에 만든 뒤 드래그 앤 드롭으로 옮기는 식으로 하시는 편이 편합니다.)

 

즉 결과적으로 경로는

 

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.12.25827\include\bits\stdc++.h

 

가 되게 됩니다.

 

stdc++.h파일의 내용은 아래에 있습니다.

 

 

복사를 하시려면, 우측 하단의 view-raw를 누른 뒤 복사하시면 됩니다. 

 

 

 

 

한국정보올림피아드 2015년도 초등부 문제 풀이 포스팅입니다.

https://www.acmicpc.net/category/detail/1353


1번 사과문제입니다.

https://www.acmicpc.net/problem/10833

apple수를 사람수로 나누면 1인당 지급되는 사과수가 됩니다.

#include <iostream>

using namespace std;

int main() {
	int N;
	cin >> N;
	
	int ans = 0;
	while(N--) {
		int std, apple;
		cin >> std >> apple;
		int cnt = apple/std;
		int total = cnt * std;
		ans += apple - total;
	}
	cout << ans << endl;
}

2번 벨트문제입니다.

https://www.acmicpc.net/problem/10834

정수로 떨어지게 되어있으므로 그냥 계산하면 됩니다.

#include <iostream>

using namespace std;

int main() {
	int M;
	bool direction = false;
	int rot = 1;
	cin >> M;
	
	while (M--) {
		int a, b;
		int dir;
		cin >> a >> b >> dir;
		rot *= b;
		rot /= a;
		if (dir == 1) {
			direction = !direction;
		}
	}
	cout << (direction == true ? "1" : "0") << " " << rot << endl;
}

3번 카드문제입니다.

https://www.acmicpc.net/problem/10835

완전탐색을 하면 시간 초과가 난다. O(3^n)이 된다. 하지만 중복탐색되는 부분을 줄이면, 즉 Memoziation원리를 적용한 Dynamic programming으로 풀 시에는 나타나는 좀더 효율적으로 풀 수 있다. dp[왼쪽남은카드수][오른쪽남은카드수]로 한다면 최악의경우 O(n^2)이므로 2000^2 = 400만으로 1초안에 풀 수 있다.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> L, R;
int n;

int dp[2001][2001];
bool chk[2001][2001];

int get(int l, int r) {
	if (l <= 0 || r <= 0) {
		return 0;
	}
	if (chk[l][r]) return dp[l][r];

	int ret;
	
	ret = max(get(l-1, r-1), get(l-1, r));
	int left_top_card_val = L[n-l];
	int right_top_card_val = R[n-r];
	if (left_top_card_val > right_top_card_val) {
		ret = max(ret, get(l, r-1) + right_top_card_val);
	}
	chk[l][r] = true;
	return dp[l][r] = ret;
}
int main() {
	cin >> n;
	L.reserve(n);
	R.reserve(n);

	for (int i=0; i < n; i++) {
		int tmp;
		cin >> tmp;
		L.push_back(tmp);
	}
	for (int i=0; i < n; i++) {
		int tmp;
		cin >> tmp;
		R.push_back(tmp);
	}
	cout << get(n, n) << endl;
}



4번 여왕별 문제입니다.

https://www.acmicpc.net/problem/10836

dfs로는 Time out이 납니다.. 그러므로 더 좋은 성능의 방법을 찾아봐야 합니다.

숫자가 감소하지 않는 방향이라고 했으니 규칙을 잘 보면, 왼쪽 끝과 위쪽 끝을 제외하고 내부쪽은 결과적으로 위쪽 값과 같은 값을 갖게 됩니다.

이러한 규칙을 이용하면 O(MN)으로 해결 가능합니다.

#include <iostream>
#include <vector>

using namespace std;

vector<int> border;

int main() {
	int M, N;
	cin >> M >> N;
	int len = M*2 - 1;
	border.resize(len, 1);
	while(N--) {
		int zero, one, two;
		cin >> zero >> one >> two;
		for (int i=zero; i < zero + one; i++) {
			border[i]++;
		}
		for (int i = zero+one; i < len; i++) {
			border[i] += 2;
		}
	}
	
	for (int i=0; i < M; i++) {
		for (int j=0; j < M; j++) {
			if (j==0) {
				cout << border[M-i-1] << ' ';
			} else {
				cout << border[M+j-1] << ' ';
			}
		}
		cout << endl;
	}
}


컴퓨터를 오래 사용하다가 보면, 컴퓨터가 많이 느려진다던지, 바이러스에 걸린다던지, 설정이 잘못되었다던지 등의 이유로 컴퓨터의 초기화가 필요할만한 상황이 있습니다. 이럴때 보통 사람들은 컴퓨터를 '포맷' 한다고 들 많이 표현을 합니다.


하지만 보통 이럴 때 사용하는 방법은 '포맷'이 아니라 '윈도우 재설치'라는 용어가 맞습니다. 간단하게 설명해서 '포맷'은 저장장치의 내용을 다 지워버리고, 새로 파일시스템을 구축하는 것이라고 보면 되고, '윈도우 재설치'는 컴퓨터의 시스템 관리 소프트웨어, 즉 운영체재를 지우고 새로 설치하는 것이라고 볼 수 있습니다.


그래서 단순히 컴퓨터가 이상해졌다고 하드디스크(혹은 SSD)를 '포맷'만 한다면 부팅이 되지 않는 그냥 고철덩어리 컴퓨터 하드웨어만 남게 되는 것이지요. 


어쨋든 용어는 바로 잡았으니, '포맷', 아니, '윈도우 재설치'를 하는 개괄적인 과정에 대해서 설명해 보도록 하겠습니다. 보통 주변의 컴퓨터를 잘 아는 사람에게 부탁하는 것이 일반적이기도 한데요, 전체적인 개념을 알고 인터넷을 조금 찾아보면 누구나 할 수 있는 과정이기도 합니다. 일단 필요한 것들은 다음과 같습니다.


1. 윈도우 라이센스 키

2. 윈도우 재설치를 할 노트북 혹은 데스크탑 컴퓨터

3. 내용이 다 지워져도 되는 8GB이상의 용량을 가진 USB 메모리 (혹은 윈도우 설치용 CD)

4. 그리고 부팅 USB를 만들때 쓸 컴퓨터


윈도우 버전에 따라서 용량이 다르기 때문에 USB 메모리가 꼭 8GB이상의 용량을 가질 필요는 없지만 안정적으로 하기 위해서는 8GB이상의 용량을 확보하는 것이 좋습니다.


컴퓨터에 관심이 크게 없으신 분들은 윈도우 라이센스에 대한 개념이 없으신 분도 있는데, 윈도우 운영체제는 10만원대 정도의 가격을 가진 '상용 제품'입니다. 즉, 돈을 받고 판매를 하는 하나의 상품이며, 정당한 대가를 지급하고 사용하는 것이 맞습니다. 그런데 보통 삼성, LG와 같은 곳에서 노트북을 사게 되면 윈도우가 기본적으로 설치되어 있는 경우가 많은데, 그런 경우는 노트북 가격에 윈도우 운영체제 가격이 포함되어 있는 것입니다. 그러한 노트북은 노트북에 붙어있는 스티커를 잘 찾아보면 윈도우 라이센스 키(시리얼 키)가 있을 것입니다. 이 키를 활용해서 윈도우 재설치를 할 수 있습니다. 혹은 이미 윈도우 운영체제를 사용하다가, Microsoft 계정으로 로그인 뒤 해당 윈도우즈 운영체제의 라이센스를 계정에다가 귀속시킨 경우, 해당 계정을 통하여 다시 라이센스를 복구할 수도 있는 것으로 알고 있습니다. 이에 대한 자세한 과정과 내용은, 다른 블로그나 Microsoft 공식 사이트, 도움말 등을 참고해 주시면 되겠습니다.


그러면 윈도우 재설치의 개괄적인 전체 흐름을 나열해보도록 하겠습니다.


1. 윈도우 라이센스 키 확보 (버전, 에디션 확인 필수!)

2. 해당 윈도우 버전에 맞는 ISO 파일 확보

3. ISO 파일을 이용하여 USB 메모리를 윈도우즈 부팅 USB로 제작

//혹은 2-3번 과정을 동시에 진행을 할, MediaCreationTool.exe를 이용하여 윈도우즈 부트 USB를 만들기

4. USB를 꽂은 상태에서 재설치 할 컴퓨터를 재부팅

5. 해당 컴퓨터의 BIOS 모드로 진입(혹은 UEFI 모드)후, 부팅 우선 순위(Boot Priority)를 변경하여 'USB 메모리'의 우선순위를 하드디스크나 SSD보다 높게 설정

6. USB로 부팅 시 윈도우 재설치 메뉴가 활성화됨. 절차에 따라서 재설치

7. 윈도우 재설치 이후 해당 하드웨어에 맞는 드라이버 파일 설치

8. 기타 필요한 한컴오피스나, MS 오피스 파일 등을 설치


전체적인 흐름은 다음과 같습니다. 2~3번 과정은 한번에 해결해주는 프로그램을 마이크로소프트에서 지원한다고 들은바가 있는 것도 같습니다. 각각의 과정에 대하여 상세하게 설명하면 하나하나 더 상세히 설명을 할 수 있지만, 그렇게 하게 되면 '간단 설명'이라는 이 포스팅의 성격과 달라지므로 이 포스팅은 여기서 끝마치겠습니다.

+ Recent posts