티스토리 뷰
.입출력
. 입출력 방식 속도
- C 표준 입출력 함수 scanf, printf (적은 메모리를 사용하지만 아래 방법보다는 느림)
단, cin보다 대용량의 데이터를 input 할 수 있음
- std::cin, std::cout 사용 시 아래 코드 적용
1 | ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) | cs |
이 코드를 적용하지 않으면 입,출력시 사용하는 버퍼를 동기화하는 것인데,
이럴 경우 C++ 표준 stream버퍼와 C 표준 stream 버퍼가 병행하여 버퍼를 사용하게 된다.
C++, C 로 stream 버퍼를 모두 사용할 수 있지만, 버퍼를 병행하여 사용하기 때문에 속도가 느려지는 현상이 발생하게 된다.
그래서 이 코드로 동기화를 해제해주면서 C++ 표준 stream만 사용하도록 하여 독립 버퍼만 사용할 수 있게 한다.
- 개행문자 "\n" 사용, cout << num << "\n";
(함수로 사용 시 편리)
1 | #define init() ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) | cs |
참고) 입/출력 속도 비교
https://www.acmicpc.net/blog/view/56
https://www.acmicpc.net/blog/view/57
. 반복문에 입력과 조건을 동시에
1 2 3 | while (scanf("%d %d", &A, &B), A&&B) { printf("%d\n", A + B); } | cs |
. 입력이 끝날 때 까지 반복
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | // 1. scanf()가 입력받은 인자의 갯수를 리턴하는 특성을 활용하는 방법 while (scanf("%d%d", &A, &B) == 2) // +. 틸트(~) 연산자 사용 // 없으면 0을 반환 while (~scanf("%d %d", &A, &B)) { printf("%d\n", A + B); } // 2. scanf()를 EOF와 직접 비교하는 방법 while (scanf("%d %d", &A, &B) != EOF) // 3. EOF가 상수 -1로 정의되어 있는 특성을 활용하는 방법 while (scanf("%d %d", &A, &B) != -1 || scanf("%d%d", &A, &B)>0) printf("%d\n", A + B); /// 4. cin.eof()를 활용하는 방법 // cin으로 입력받은 값이 없으면 cin.eof()는 true를 반환 while (true) { cin >> A >> B; if (cin.eof() == true) { | cs |
--
1 | for (;~scanf("%d", &num); i++) | cs |
--
1 2 3 4 5 | freopen("input.txt", "rt", stdin); int n; scanf("%d", &n); | cs |
1 2 3 4 5 6 7 | #include <fstream> ifstream cin; cin.open("input.txt"); char a[100]; cin >> a; | cs |
--
.문자열
.string 문자열을 char로 받기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | char str[20]; int i; scanf("%s", str); // fread(str, 1, sizeof(str), stdin); for (i = 0; str[i]; i++) putchar(s[i]); // printf("%c", s[i]); puts(" "); // 문자열 길이까지 탐색 for(i = 0; a[i] != '\0'; i++) // 10자씩 끊어서 입력받기 while (~scanf("%10s", str)) puts(str); | cs |
.공백이 포함된 문자열 입력 받기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // gets char a[100]; gets(a) // string getline string str; getline(cin, str); int len = str.length(); // array getline char arr[100]; cin.getline(arr,100) // while (fgets(arr, sizeof(arr), stdin)) // scala char a; while(scanf("%c",&a)!=-1) | cs |
--
1 2 3 4 5 | char str[1000000]; str[fread(str, 1, sizeof(str), stdin)] = 0; for (int i = 0; str[i]; ++i) ... | cs |
--
. 한 글자씩 받기
- 문자열이 붙어있는 경우
- cp+1 부터 저장
1 2 3 | int cp[51]; scanf("%1d", cp+1); | cs |
--
.메모리
.레지스터 변수
1 | register int i, j; | cs |
- 메모리 대신 CPU의 레지스터를 사용 -> 일반 변수보다 빠른 속도 (단, 레지스터는 개수가 한정)
- 레지스터 변수는 변수가 CPU만 사용하므로 메모리에는 생성되지 않음 (&로 메모리 주소 참조 불가)
- 반복 횟수가 매우 많을 때 유용
--
. 메모리 초기화
1 2 3 4 | #include <string.h> int cache[2500]; memset(cache, -1, sizeof(cache)); | cs |
--
.벡터 초기화
--
1 2 3 4 5 | // 1차원 배열 Board.resize(N, 0) // 2차원 열 Board.resize(N, vector<int>(N, 0)); | cs |
--
.Stream Buffering 변경 : setvbuf
1 2 3 4 | char in[1<<19]; // Buffer stream 객체 생성(fopen 도 사용) setvbuf(stdin, in, _IOFBF, sizeof(in)); setvbuf(stdout, in, _IOFBF, sizeof(in)); | cs |
--
.변수
. min, mix 표기
1 2 3 4 5 6 7 8 | int max = 1e6 // 1000000 int min = -1e6 // -1000000 int max2 = 2147000000; int min2 = -2147000000; double max = 1e-6; // 0.000001 double min = -1e-6; // 0.000001 | cs |
. ASCII Code
1 2 3 4 5 | 'A' ~ 'Z' = 65 ~ 90 'a' ~ 'z' = 97 ~ 122 0 ~ 9 = 48 ~ 57 | cs |
출처 : https://shaeod.tistory.com/228
.동적 vector 생성
1 2 3 4 5 6 7 | #include<vector> using namespace std; scanf("%d", &n); vector<int> a(n); | cs |
.동적 배열 생성
1 2 3 | int *pArr = new int[n+1]; ... delete[] pArr; | cs |
.첫 번째 or 마지막 원소 참조
1 2 | start = *(vt.end()-1); end = *(vt.begin()); | cs |
.여러 변수에 같은 같을 저장할 경우
1 | p2=p3=p5=1; | cs |
.구조체
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | struct Lecture { int money; int day; // 생성자 Lecture(int a, int b) { money = a; day = b; } // sort()에서 오름차순 정렬을 위해 사용하는 < operator 를 오버라이딩 bool operator<(const Lecture& b) const { // 앞에 자료가 크다면 true를 반환하여 < operator 동작 시 내림차순으로 정렬 return day > b.day; } } | cs |
.연산
.세 수의 최솟값
1 2 3 4 | if (n1 < n2) min = n1; else min = n2; if (n3 < min) min = n3; | cs |
.회고
ㅇ문자열 처리
- 문자열은 개행문자 '\0' 으로 끝남
ㅇ변수
- 전역변수로 선언하는 이유는, 원소를 0으로 자동 초기화시켜주기 때문(단, 지역변수보다 메모리를 더 차지)
- PS 코딩 때는 변수명도 짧고 센스있게 지어보기(물론 실무에서는 자세히 지어주는게 좋지만..)
- 변수 초기값 및 초기화 위치 확인
- 최대 N의 크기만큼 배열을 생성하는 것 보다 vector의 동적 할당을 이용하는 방법(N이 클 경우 유리)
ㄴ vector 를 동적으로 생성 시 기본적으로 원소를 0으로 초기화
- 배열을 사용하지 않고도 pre, now 변수로 문제를 해결해내는 센스
- for문을 사용하지 않고 증감연산자로 해결할 수 있다면, 최대한 반복문을 사용하지 않는 것이 속도 성능에서 유리!
- 다수의 원소값을 얻고 싶은게 아니라 소수의 원소값을 얻는 것이 목적이라면 배열을 사용하지 안고 변수만으로 원하는 값을 얻어보자!
ㅇ연산
- ASCII Code 를 잘 활용해보자
- 반복문 안에서 입력과 처리를 동시에
- "소인수분해"는 합성수를 "소수의 곱"으로 나타낸 방법!
- if and for collaboration 은 while 문으로 사용해보자
- 배열 참조와 동시에 증감연산자를 사용하면 코드가 더 깔끔해진다. v[p++];
ㅇ 처리
- "더 이상 처리할 작업이 없을 경우 '-1' 출력"과 같이 특수 상황의 경우 미리 처리하기
ㅇ 알고리즘 구현
- DFS 문제는 스택을 그려보면서 함수를 만들어나가도록!
ㅇ기타
- 문제 잘못 이해하고 풀면 끝장이다.. 문제 제대로 이해하고 재정의한 후 풀자.
- 자료구조의 특성, 장점을 잘 활용해서 풀자!
.기타
. LNK 1168 Error
- cmd -> taskkill /f /im [projectName].exe
[ 알고리즘 대회에 필요한 수학 ]
- https://algospot.com/wiki/read/알고리즘_대회에_필요한_수학
[ 읽어보면 좋은 PS 공부 방법 ]
- https://subinium.github.io/how-to-study-problem-solving/
'PS > PS_Note' 카테고리의 다른 글
[Java] PS Coding Tip(~ing) (0) | 2020.07.21 |
---|---|
[Python] PS Coding Tip (~ing) (0) | 2020.05.13 |
[C/C++] STL map 활용 (0) | 2020.05.13 |
[C/C++] 자주 사용하는 C++ STL 자료구조 (vector, pair, queue, priority_queue) (0) | 2020.05.02 |
[C/C++] C++ Algorithm Note (~ing) (0) | 2020.04.23 |