일반적으로 1억번(100,000,000 = 10^8)의 연산 = 1초의 실행시간
(당연한건데 자꾸 헷갈려서.. 4개단위로 끊어서 보자고)
처리할 데이터가 많아질수록 차이가 급격하게 벌어짐
→ 2억번 이하의 연산을 해야되는구나! 도출하기
백만개의 데이터를 2초 안에 정렬해야하는 경우, 버블정렬(n^2) vs 병합정렬(nlogn)중에는 당연히 후자를 골라야함
why? nlogn 백만 -> 2천만번 < 2억번
가장 많이 중첩된 반복문의 시간복잡도를 살펴볼것!! (상수는 무시)
→ 자료형 체크!!! (overflow 발생했을 가능성 큼)
ex. int -> long long으로 바꿔보자
(값, 포인터) 노드라는 것을 포인터로 연결한 자료구조
C++ 표준 라이브러리에 있는 자료구조 컨테이너 중 하나
배열의 특징을 가지면서 배열의 단점을 보완한 동적 배열의 형태
#include <vector>
해줘야 사용 가능!
배열이 바뀌지 않을때, 구간합을 구하기 유용하다
배열 각 칸의 누적합을 저장해두고 특정 부분의 구간합을 구해야할 때 사용
배열 A
누적합 배열 S
S[i] = S[i-1] + A[i]
2~5 사이의 누적합 : S[5] - S[1]
→ nlogn의 시간복잡도인 정렬 + 두 수를 체크해야 하므로 투 포인터 (O(N))
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cin.tie(NULL);
}
ios::sync_with_stdio(false);
: C에서의 입출력 라이브러리 stdio, C++에서의 입출력 라이브러리 iostream의 버퍼 동기화를 분리. C++만의 버퍼를 사용해서 검사할 버퍼의 크기가 줄어들어 속도 향상
(C언어 입출력함수 printf, scanf등 사용 불가)
cin.tie(NULL);
: cin, cout의 tie를 풀어준다. cin, cout은 기본적으로 tie되어있어 cin을 사용하기 전에 cout에서 출력할 값을 내보냄. 출력할 값을 버퍼에서 내보내는 flush 과정을 건너뛰므로 속도 향상
(cout에서 입력을 받기 전에 무언가를 표시할 때마다 cin을 수동으로 플러시해줘야 함)
endl 대신 \n
쓰기 : endl은 개행 후 버퍼를 비워주는 역할까지 하므로 단순 개행문자를 사용하는 것이 속도가 조금 더 빠르다
cin
: 띄어쓰기(공백) 기준으로 입력받음. \n
만나면 저장하지 않고 버퍼에 넣어준뒤 그 전까지의 입력만 받음getline
: 3번째 파라미터로 주어지는 것을 기준으로 입력을 분할하여 받음. 디폴트값은 \n
. cin과 달리, \n
자체를 저장 가능백준 1377. 버블소트
문제에서 시키는대로 버블정렬하면 시간초과난다. N은 50(510^5)만이므로 N^2를 하면 기준시간 2초(2억번 210^8)에 절대 못 들어온다.
따라서 버블정렬 내에서 최적화를 시켜주는 것이 아니라 문제에서 출력하는 값이 정확히 무엇인지를 판단하는 것이 중요하다
문제에서 출력하는 값 i
는 몇 번의 swap이 일어났는지 그 횟수+1를 출력해주는 것이다. 즉, 반복문이 몇 번 돌았는지를 체크해주는 것!
핵심 아이디어는 정렬 후 인덱스 값 - 초기 인덱스값
의 max값이 최대 반복 횟수와 같다는 것이다.
따라서 nlogn의 시간복잡도를 가지는 algorithm 라이브러리의 sort함수를 실행해준 뒤 인덱스값의 차이를 구해주면 된다.
(어렵다)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N = 0;
cin >> N;
// (값, 인덱스) 쌍으로 넣어주기
vector<pair<int, int>> A(N);
for (int i = 0; i < N; i++) {
cin >> A[i].first;
A[i].second = i;
}
sort(A.begin(), A.end());
int Max = 0;
for (int i = 0; i < N; i++) {
if (Max < A[i].second - i) {
Max = A[i].second - i;
}
}
cout << Max + 1;
return 0;
}