![코테 준비하기 - 기본 사항들](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0NkPw%2FbtrME1R8hTw%2FRdOFQ4OKPQeTU8y0uqD4Ik%2Fimg.png)
예전부터 조금씩 하기는 했지만 ..작은기업을 준비하던 나에게 코테는 우선순위가 밀려 많이 하지는 못했다 , 그래도 길게보고 조금씩 준비해보려고 한다.
언어 선택
언어는 C++로 선택했다.
유니티 때문에 C#을 주로 사용했긴 하지만 코테에 있어서는 C++을 추천하는 사람들이 많기도 하고, C++이 뭔가 재밌다.
STL의 숙련도도 쌓을 수 있을거라고 생각한다.
bits/stdc++.h
C++의 STL을 이용하기 위해 여러가지 헤더 파일들을 포함시키는데, 매번 문제를 풀때마다 포함시키는것도 여간 귀찮은 일이 아니다.
이 헤더파일을 열어보면 많이쓰는것들을 몽땅 모아놨다.
주의할점 이라면 우리가 푸는 코딩테스트 사이트들의 컴파일러는 gcc 컴파일러고 이 헤더파일이 기본 내장 되어있지만, 우리가 많이쓰는 비주얼 스튜디오는 msvc컴파일러를 쓰기때문에 비주얼 스튜디오에서 쓰려면 파일을 넣어줘야 한다.
아래의 경로는 내가 넣어둔 경로인데, bits폴더를 따로 만들어서 위의 파일을 넣어주면 된다.
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\bits
하지만 당장 내가 봤던 회사의 코테에서는 회사 노트북에 있는 비주얼스튜디오에서 풀어야 했기에 위의 헤더파일을 사용할 수 없었고, 삼성 코테에서는 저 헤더파일을 쓰지 못하게 한다는 내용을 본 것 같다(확실하진 않다).
그러므로 필요한 기능이 어디에 담겨있는지는 꼭 알아두어야 한다.
첨엔 이름이 익숙하지 않아서 이름을 다시 보고 그랬는데,
using namespace std 할때 std랑 c++을 더해주면 끝나는 거였다.
stdc++
시간복잡도와 공간복잡도
무턱대고 구현을 할것이 아니라 시간제한과 메모리제한을 보고 코드를 짜야한다.
내가 짜는 알고리즘의 시간복잡도와 사용될 메모리를 문제에 맞게 잘 판단하고 구현해야한다.
ios::sync_with_ stdio(0)
함수인자는 bool 이지만 빠르게 적기위해 보통 0 을 적는다.
기본적으로 printf/scanf & cout/cin 의 사용을 위해 C stream과 C++ stream을 동기화 시켜놓는다고 한다.
printf와 scanf만 쓴다면 상관없지만 , cout과 cin만 쓴다면 C stream과의 동기화를 끊는게 프로그램 수행 시간에서 이득을 챙길 수 있다.
동기화를 끊어놓는다면 혼용하여 쓰면 안된다.
비주얼 스튜디오에서는 동기화를 끊는걸 허용을 안해주지만 gcc컴파일러는 영향이 있다고 한다.
cin.tie(0)
입력을 받으면 바로 콘솔로 출력을 하는것이 아니라 버퍼에 넣었다가 비워지면 콘솔로 출력을 하게 되는데,
그래서 기본적으로는 cin 수행전에 cout버퍼를 비워준다고 한다.
버퍼를 비우지 않으면 내가 원하는 순서대로 콘솔에 출력이 되지 않을수있으나
(ex. (입력 - 출력) 순으로 나와야 하는데 (입력 - 입력 - 출력 -출력) 이렇게 나올 수 있다) ,
코딩테스트에서는 출력값으로만 채점을 하기 때문에 버퍼를 비우는 작업을 할 필요가 없다.
cin.tie(nullptr)은 수행전에 cout버퍼를 비우지 않게끔 하는 코드이다.
이 또한 빠르게 쓰기 위해 0을 넣는다.
endl은 쓰지 않기
나도 처음 배울때 endl을 많이 써서 코테때도 endl을 많이 썼는데 시간 초과가 나오는 경우가 있었다.
endl은 개행문자를 출력하고 출력 버퍼를 비우는 작업을 한다.
출력 버퍼를 계속 비울 필요가 없기 때문에 줄을 넘길 일이 있다면 '\n'를 쓰도록 하자.
함수인자 값 생각하기
C#에서 out,ref로 원본을 넘기는것 처럼 , 함수 인자를 넘길때 잘 생각해야 한다.
#include<bits/stdc++.h>
using namespace std;
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 5;
int b = 0;
swap(a, b);
cout << "a: " << a << endl << "b: "<< b;
}
이렇게 넘기면 인자로넘긴 a,b가 복사가 이루어져 넘겨지기 때문에 원본에 영향을 주지 못한다.
#include<bits/stdc++.h>
using namespace std;
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
이런식으로 매개변수를 레퍼런스 형으로 받거나 포인터를 통해 주소를 넘겨주어야 원본을 바꿀 수 있다.
#include<bits/stdc++.h>
using namespace std;
void swap(vector<int> a)
{
int temp = a[0];
a[0] = a[1];
a[1] = temp;
}
int main()
{
vector<int> v(2);
v[0] = 2;
v[1] = 5;
cout << "\n스왑 전\n" << "a: " << v[0] << " b: " << v[1] << endl;
swap(v);
cout << "\n스왑 후\n" << "a: " << v[0] << " b: " << v[1] << endl;
}
STL의 vector를 쓸때도 마찬가지다.
그냥 벡터를 넘긴다면 값을 복사한다.(벡터안의 요소들을 다 복사한다고 하니 주의)
그래서 원본에 영향이 없다.
#include<bits/stdc++.h>
using namespace std;
void swap(vector<int>& a) //레퍼런스
{
int temp = a[0];
a[0] = a[1];
a[1] = temp;
}
int main()
{
vector<int> v(2);
v[0] = 2;
v[1] = 5;
cout << "\n스왑 전\n" << "a: " << v[0] << " b: " << v[1] << endl;
swap(v);
cout << "\n스왑 후\n" << "a: " << v[0] << " b: " << v[1] << endl;
}
하지만 간단히 레퍼런스로 넘겨준다면 주소값을 넘기기 때문에 복사도 일어나지 않고 원본을 바로 참조할 수 있다.
기본 문제 풀어보기 - 백준 2444번 <별 찍기 - 7>
그냥 예제 출력 모양대로 별을 찍으면 되는 간단한 문제다.
for문을 크게 2번 돌리면 편했는데 괜히 새벽에 오기가 생겨서 하나에 넣느라 애를 좀 먹었다.
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n = 0;
cin >> n;
for (int i = 0; i < 2 * n - 1; i++)
{
if (i < n)
{
for (int j = 0; j < n - i - 1; j++) cout << ' ';
for (int k = 0; k < 2 * i + 1; k++) cout << '*';
cout << '\n';
}
else
{
for (int l = 0; l < i - n+1; l++) cout << ' ';
for (int z = 0; z < 2 * n - (3+((i-n)*2)); z++) cout << '*';
cout << '\n';
}
}
}
기본 문제 풀어보기 - 백준 2309번 <일곱 난쟁이>
9명의 난쟁이 중에 2명의 가짜 난쟁이를 가려 찐 7명의 난쟁이를 찾는 문제다.
7개의 수를 모두 더해 딱 100이되는 수들을 오름차순으로 나열하여 출력하면 된다.
원래는 하나하나 더해서 검사하는걸로 시도하다가 무식한 방법같아서 다른 방법을 생각했다.
일단 다 더해놓고 2개를 빼서 100이 되면 뺀 숫자들을 제외시키고 출력하는 방법이다.
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int smallman[9] = { 0, };
int sum = 0;
for (int i = 0; i < 9; i++)
{
cin >> smallman[i];
sum += smallman[i];
}
sort(smallman, smallman + 9);
for (int i = 0; i < 8; i++)
{
for (int j = 1; j < 9; j++)
{
if (sum - smallman[i] - smallman[j] == 100)
{
for (int k = 0; k < 9; k++)
{
if (k == i || k == j) continue;
cout << smallman[k] << '\n';
}
return 0;
}
}
}
return 0;
}
1. 9개의 난쟁이를 입력받고 sum에 다 더해주었다.
2. 오름차순으로 미리 정렬을 한다.
3. i와 j의 인덱스를 총 합에서 뺐을때 100이된다면 i , j를 뺀 요소들을 출력하고 리턴시켰다.
완전 기본적인 문제들과 별찍기, 응용문제 등 기본 구현문제들을 풀어봤다.
아직 많이 풀어본게 아니라 구현에 있어서 어려움이 있는데 , 공부를 하다보면 나아지지 않을까 싶다.
'프로그래밍 공부 > 코딩테스트 준비' 카테고리의 다른 글
#2 코테준비 - 연결리스트 (0) | 2022.09.22 |
---|---|
#1 코테 준비 - 배열 (0) | 2022.09.21 |
LeetCode 문제 풀어보기 - 278번 First Bad Version (0) | 2022.07.22 |
LeetCode 문제 풀어보기 - 35번 Search Insert Position (0) | 2022.07.16 |
LeetCode 문제 풀어보기 - 704번 Binary Search (0) | 2022.07.16 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!