본문 바로가기

Study/Algorithm

코딩테스트에서 신경쓸 것

 

첫 번째 테스트케이스만 맞고 두번째부터 틀린다면 : 전역변수 초기화

전 역 변 수 초 기 화

 

뭔가 이상하다 dp인데 너무 복잡하다싶으면 : 조건 확인하기

문 제 조 건 확 인

 

너무 국소적인 부분으로 파고든다 싶으면 : 천천히 문제 다시 읽기

문 제 다 시 읽 기

 

최소값, 최대값 입력해봐서 결과 확인하기

최 대 최 소 입 력

 

테스트케이스끼리 순서 바꿔서 넣어보기. input받다 break; return;하면 다음 테스트케이스에 영향감

순 서 바 꿔 보 기

 

 

 

1. 전역변수 초기화

solution함수에서 계속 쓰는 전역변수.

vector에 push_back하기 전에 초기화 했는가?

- vector.clear() ; 원소만 지움. 메모리 할당한 것은 그대로!

- 메모리까지 아예 초기화하는 방법; (vector<int> v)

    1. v = {};

    2. v = vector<int>();

    3. vector<int>().swap(v);

 

 

2. cin 후 getline전에 cin.ignore()

cin하고 getline하기 전에 버퍼를 비웠는가?

cin.ignore()를 했는가?

 

cin >> a;

cin.ignore();

getline(cin, str);

 

3. 이차원 벡터 초기화 방법

cache = vector<vector<int> >(size,vector<int>(size,-1));

 

4. int -> string, string -> int

int -> string : to_string

string -> int : int amount = atoi(num.c_str());

 

5. 이쁘게 깔끔하게 짜기 x 일단 빠르게 뭐라도 짜기

 

 

6. map 사용법

map<string, int>::iterator it;

it = accounts.find(account);

if(it != accounts.end()){//찾아서나온상태}

 

map 초기화 : m.clear();

 

 

7. MOD

mod가 주어지는경우 계산시 mod적용

answer /=MOD

 

 

8. 벡터에서 중복 제거

sort -> erase(unique());

 

sort(v.begin(), v.end());

v.erase(unique(v.begin(),v.end()), v.end());

 

원리 :

예) v = {1 3 2 5 6 3 2 4}

- sort(v.begin(), v.end())

결과로 정렬된 벡터가 나온다.

{1 2 2 3 3 4 5 6}

 

- unique(v.begin(), v.end())

unique는 중복된 원소를 맨뒤로 보내고 쓰레기값이 시작되는 인덱스를 리턴한다

v = {1 2 3 4 5 6 5 6}, 6리턴 (초록색이 시작되는 인덱스 리턴)

unique를 취한 결과는 {1 2 3 4 5 6 2 3}이 아니다! 유니크값 이후로는 그냥 쓰레기값이다!

 

- erase(v.begin(), v.end())

v[begin, end)를 지운다

 

 

9. 내림차순 정렬

sort(v.begin(), v.end(), greater<>());

 

아니면 그냥 벡터값에 -를 붙여서 정렬해도 괜찮다

쓸때만 -다시 해제하면 되지

v = -v

sort(v.begin(), v.end())

 

10. 문제 조건 확인하기

dp인데 뭔가 너무 변수가 많은데..?싶으면 문제의 조건을 확인하자

왜 못봤니 왜 ㅠㅠ

너비 k라는 변수가 조건으로 주어졌었다는걸 왜 못봤니

다음부턴 조건을 잘 확인하자!

식 짜기 전에 조건부터 확인할 것!

 

 

11. 스트링 공백 제거

ids.erase(remove_if(ids.begin(), ids.end(), isspace), ids.end());

names.erase(std::remove(names.begin(), names.end(), ' '), names.end());

 

원리:

remove나 remove_if 함수는 지울 문자들을 맨 뒤로 보내고, 보낸 위치를 리턴한다.

즉, "a b c d e"에 remove나 remove_if로 ' '를 지우도록 취하면

"abcde    "로 만들어버리고, ' '가 시작하는 인덱스(5)를 리턴한다.

 

remove()함수가 값을 실제로 지우는것은 아니기때문에

erase(begin, end)로 지워줘야 한다.

 

 

12. 공백 기준으로 string 단어 자르기

 for(string& ids : id_list){
        //문자열에서 이름 분리하기
        vector<string> names;
        size_t cur, pre = 0;
        cur = ids.find(' ');
        while (cur != string::npos)
        {
            string substring = ids.substr(pre, cur - pre);
            names.push_back(substring);
            pre = cur + 1;
            cur = ids.find(' ', pre);
        }
        names.push_back(ids.substr(pre, cur - pre));
}

 

 

13. foreach문에서 map을 접근할때

map<string, int> mapping;

 

# auto& 로 접근

for(auto& m : mapping){

     cout << m.first;

     m.second = "1";

}

 

# 직접 자료형 지정해서 접근

for(pair<const string, int>& m : mapping){

    cout << m.first;

    m.second = "1";

}

 

map에 range-based for로 접근하려면 const를 붙여줘야 한다.

왜냐면 map의 first값은 key이기 때문이다. key는 불변!

 

 

14. 소수점 출력하기

cout.precision(); //전체 자리수 설정

cout << fixed;  //소수점 아래 고정자리수 설정

printf("%.9f",n); //소수점 아래 9자리 출력

 

double solve(int n, int m){

    cout << fixed;

    cout.precision(9);

    return (double)n/m;

    cout.unsetf(ios::fixed);

}

 

15. cin, cout 빨리하기

cin.tie(NULL);

ios::sync_with_stdio(false);

endl대신 "\n"이용하기

 

이 방법쓰면 cout할때 flush 해줘야한다. 근데 백준문제에선 따로 안 해줘도 맞았다. .뭐지

사실 그냥 scanf, printf를 쓰는 게 편하다.

 

 

16. string 생성자

string str(5, '*'); //*****

string str("Hello world", 4); //Hell

string str("Hello world", 6, 5); //world

위는 숫자만큼 char 반복, " "대신 ' '이용

아래는 문자열에서 글자수만큼 자른다

 

첫번째 인자로 이미 생성된 string 변수를 넣을 경우는 substring처럼 동작한다.

string hello = "Hello world";

string(hello, 4);  //o world

string(hello, 6, 5); //world

 

16. 입력 끝 판단하기 (EOF)

cin >> n >> m;

if(cin.eof()) return;

 

 

17. string 대문자, 소문자 변환

std::transform(str.begin(), str.end(), str.begin(), ::tolower);

std::transform(str.begin(), str.end(), str.begin(), ::toupper);

 

 

18. for()안에 인덱스를 조작하는 경우, 증감연산자도 확인할것

기존에 틀렸던 코드.

i에 값을 할당해줬는데 for(i++)를 돌면서 i가 증가해 결과가 다르게 나옴

for(int i = 0; i<str.length(); i++){
        size_t pos = str.find_last_of(str[i]);
        size_t rpos = str.find_first_not_of(str[i], i);
        i = rpos;  //i에 값을 할당했으나 for문이 다음으로 넘어가면서 +1이 된다
    }

 

고친 코드. i가 자동으로 증가하지 않음

size_t i = 0;
while(i != string::npos){
    size_t pos = str.find_last_of(str[i]);
    size_t rpos = str.find_first_not_of(str[i], i);
    i = rpos;
}

 

19. 동적계획법 사용시 메모리 초과 주의할것. bottom-up도 생각해보자

동적계획법을 쓰는데 그냥 맨날 쓰듯이 cache잡아서 썼더니 메모리 초과가 났다.

재귀로 돌림 + cache[10000+1]개했더니 틀렸다. 윈도우는 스택 사이즈 1MB까지만 잡기 때문이다.

그럴때는 bottom-up방식도 고려해보자.

bottom-up고려한 방법 : 백준 10844 쉬운 계단수 포스팅

 

 

20. 인덱스 범위 확인

n개 입력값이 들어왔을때, 배열을 v(n)으로 초기화하는지 v(n+1)로 초기화하는지 주의

재귀나 for문 돌릴때도 for(; i<=n)인지 for(; i<n)인지 주의

 

 

21. bfs같은걸로 path 짤 때 reverse 확인

 

    string path="";
    int cur = b;
    while(cur != parent[cur]){
        int next = parent[cur];
        path += DSLR[cur];
        cur = next;
    }
    reverse(path.begin(), path.end());	//주의!
    return path;

path string 맨뒤에다가 경로 붙일때

최종경로는 reverse한거 잊지말기!!

 

 

22. cout 자리수, 정렬

cout.width(10); //10자리 고정. printf(%10d) 이런것

cout.fill('-'); // 자리수 빈곳을 -로 채우기

 

정렬

cout << left;

cout << right;

 

참고


map auto&:

https://blog.petrzemek.net/2016/08/17/auto-type-deduction-in-range-based-for-loops/

 

Auto Type Deduction in Range-Based For Loops | Petr Zemek

Have you ever wondered which of the following variants you should use in range-based for loops and when? auto, const auto, auto&, const auto&, auto&&, const auto&&, or decltype(auto)? This post tries to present rules of thumb that you can use in day-to-day

blog.petrzemek.net

 

cin, cout 빠르게:

https://www.acmicpc.net/board/view/22716

 

글 읽기 - 추가 설명 및 다른 언어 빠른 입출력 방법

댓글을 작성하려면 로그인해야 합니다.

www.acmicpc.net

 

'Study > Algorithm' 카테고리의 다른 글

백준 #9019 : DSLR  (0) 2020.05.04
[백준] #10844 쉬운계단수  (0) 2020.04.15
코 드 조 아  (0) 2019.11.17
[2017 카카오 예선] 보행자 천국  (0) 2019.09.04
[동적계획법테크닉] 3. 광학 문자 인식  (0) 2019.08.21