언어/C++

[C++] ICPC 25W 1회차 - 알고리즘과 시간복잡도

rngPwns 2025. 1. 25. 07:39

1. 알고리즘이란?

  • 수학과 computer science에서
    • 유한열
    • 수학적으로 엄격한 지침
    • 특정 종류의 문제 해결 or 연산수행에 사용

2. C++

  • int a; a=3 / int b=5; / int c=a+b;
  • 자료형

1. 정수형: int, long long, unsigned int, unsigned long long

 

2. 실수형: float, double, long double (float보다 double이, double보다 long double이 더 정확(저장값과 실제값의 오차가 더 작음)

 

3. 문자 및 문자열

#include <iostream>
#include <string>

int main(){
	char a='a';//char은 작은따옴표로 감싸기
    std::string hello="ICPC Sinchon 25W";//string은 큰 따옴표로 감싸기, string 헤더파일을 include 해줘야 사용가능
    }

 

4. 자료형

  • boolean: 참 또는 거짓
    • bool t=true;
    • bool f=false;

5. 입출력

#include <iostream> //헤더포함
 using namespace std; //namespace를 std로 지정->함수나 객체가 정의된 공간지정 의미
 //같은이름을 가진 함수나 객체가 동일한 공간에 있을 경우 서로 충돌할 수 있기 때문에 namespace를 통해 구분
 //해당 줄이 없을 경우 내장함수를 사용할 때 반드시 앞에std:: 붙여줘야함(std::cin, std::cout 등)
 
 int main() {
 	int a, b;
 	cin >> a >> b; // 3 5 //입력은 cin, 출력은 cout 사용
    //cin >> n : 값이 n으로 들어온다. cout << n: 값이 n에서 나간다.
 
 	cout << a << ' ' << b << '\n';
 		// 출력:3 5
 	cout << "Hello ICPC Sinchon\n";
 		// 출력:Hello ICPC Sinchon
 	cout << "Hello ICPC";
 	cout << " Sinchon 25W";
 		// 출력:Hello ICPC Sinchon 25W
        
        //return 0; -명시적으로 종료위치에 작성가능(코드실행 중간에 멈출때도)
 }
  • std::endl도 줄바꿈에 해당하지만 버퍼를 비우는 작업 추가진행 -> 입출력 느려지고 시간초과 발생 원인이 될 수 있음

 

6. 빠른 입출력

#include <iostream>
using namespace std;

int main(){
	ios::sync_with_studio(0);
	cin.tie(0);

	//code goes here
}
  • cin을 사용하는 경우 입력받기 전 위 코드 두 줄 추가해야 입력 빨라짐
  • C처럼 C++도 scanf, printf 사용가능. 이 두 함수도 빠른입출력 해당
  • cin/cout과 scanf/printf 섞어 쓸 경우 ios::sync_with_stdio(0); 적용하면 안됨(애초에 섞어쓰지 마세여)

7. 산술연산자

#include <iostream>
using namespace std;

int main(){
	int a=3, b=5;
	cout << a+b << '\n';
	cout << a-b << '\n';
	cout << a*b << '\n';
	cout << a/b << '\n';
	cout << a%b << '\n';
}
#include <iostream>
using namespace std;

int main(){
	int a=3, b=3;
	cout <<a<<'\n'; //3
	cout <<+a<<'\n'; //3
	cout <<-a<<'\n'; //-3

	a+=b;
	cout << a << '\n'; //6
	b*=a; b-=a; b\=a; b%=a;
	cout << b << '\n'; //?

	cout << a++ << '\n'; \\6
	cout << a << '\n'; \\7
	cout << ++a << '\n'; \\8
}

 

8. 비교연산자 - C랑 똑같음

 

9. 논리연산자 - C랑 똑같음

  • 반환되는 값은 연산결과에 따라 true 또는 false

#include <iostream>
using namespace std;

int main(){
	int a=3, b=5, c=3, d=4;
	cout <<((a==c)&&(b>=d))<<'\n'; //1
	cout <<((a==c)||(b>=d))<<'\n'; //1
	cout <<!(a>0);<<'\n'; //0
}

 

10. 조건문 - C랑 똑같음

11. 반복문 - C랑 똑같음

12. 배열

#include <iostream>
using namespace std;

int arr1[5];
int arr2[5]= {1,2,3,4,5};

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);

	for(int i=0; i<5; i++){
		cin >> arr1[i];
}
arr2[2]=6;
for(int i=0; i<5; i++){
	cout << arr2[i] << ' ';
}// 1 2 3 4 5

 

13. 함수

void fun1(int x, int y){ //반환값 없는 함수
	cout << x * y << '\n';
    }

int fun2(int x, int y){
	return x*y;
    }
int fun3(int x, int y){
	fun1(x,y); // 함수 안에서 함수 호출 가능
    return fun2(x,y);
   }

 

 

3. 시간복잡도

 

시간복잡도 분석

  1. 코드의 i번째 줄을 한 번 실행하는 시간/비용 = Ci라 한다.
  2. 각 줄이 코드가 실행되는 동안 몇 번 실행되는지 계산
  3. 2.의 결과와 해당하는 Ci값을 곱한 후 전부 더해준다. -> f(n)이 나옴
  4. 상수 계수를 무시하고 적은 결과 ->  big-O natation
#include <iostream>
 using namespace std;
 
 int main() {
 	int n; // 1
 	cin >> n; // 2
 	int sum3 = 0; // 3
 	for(int i = 1; i <= n; i++) {
 	// 4
 		for(int j = 1; j <= n; j++)
 		{ // 5
 			sum3 += i ∗ j; // 6
 			}
 		}
 }
  • 1,2,3번 줄은 한 번만 실행
  • 4번줄은 n번 반복되는 for문 -> n번 실행
  • 5번줄은 n번 반복되는 for문, 4번줄에 있는 for문 안에 있어서 n*n=n^2번 실행
  • 6번줄도 n^2번 실행
  • f(n) = C1 +C2 +C3+C4n+C5n^2+C6n^2 ----> f(n) =O(n^2)

실행시간 예측하기

  • 시간복잡도는 프로그램의 실행시간 결정하는 절대적 기준 x
  • 연산의 종류에 따라 소요시간 달라짐, 캐싱 등의 요인으로 인해 더 나은 시간 복잡도를 가진 알고리즘도 실제로 특정 데이터크기에서는 더 느릴 수 있음
  • big-O notation에서 무시하는 상수계수를 포함하면 더 자명
  • C++ 기준으로 10^8개의 연산을 1초에 처리할 수 있다고 가정하면 계산 편리
    • 가벼운 연산만 포함하면 이보다 더 많은 연산도 시간 내 실행 가능-> 그냥 코드가 통과할지, 시간 초과 판정을 받을지 예측하는 참고값 정도로 활용하자~!