kyaryunha   6년 전


주유소란 문제를 풀고 있고요..(BOJ 13308) // 13308 질문글로 올리지 않고 일반 질문글로 올린 이유는, 문제에 대한 질문은 아니기 때문입니다..!


http://jason9319.tistory.com/2... 

이 분의 코드를 보고 공부중입니다 0_0..!! 


다름이 아니라, 

1. 코드 중 auto..의 사용법이 궁금합니다. auto 잘 모르겠어요 ㅠㅠ... 

그냥 int형 배열도 아니고, 저거 막.. vector<vector<pair<ll, ll>>> 이렇게 생긴 배열 auto 할땐 대체 next가 어딜 가르키는 걸까요....(몽춍..)

2. pq.push할때  pair<int,int>()이런식으로 푸시하는 것만 알고 있었는데,

  {}이렇게 푸시하는 방법도 있더라고요..! ((왠지 편해보임))


근데 {}쓰면 막 아래 파랑파랑한 warning 뜨는거 왠지 기분 쨩나쁨ㅁ...... 

고로 전 그냥 {}쓰지 않고 싶습니다..만 그것도 잘 못합니다 ㅠㅠ.. 


흡.. 그리고.. 전  pair<int,int>() 이런 식으로만 푸시할줄 아는데... 뭔가 변형된거 어렵..

 혹시 vector<vector<pair<ll, ll>>>

이런 배열에 푸시할때, {} 안쓰고 pair<>로 코딩 하려면 어떻게 해야 할까요///...



3. 아래는 위의 블로그 링크 중 제가 이해가 잘 안가는 그 부분인데요..

아래 3줄을 auto 안쓰고 , 그냥 일반적인? for문 형식으로, 그리고 {}안쓰고 pair<> 같은거 써서 코딩하는 방법으로  고친 코드 알려주시면 감사하겠습니다//!! 



몬가 그냥 int 형 배열도 아니고 괴상한 형태의 배열들은 네이버에 검색해도 뭐가 잘 안떠요 ㅠㅠ

물어볼 곳도 딱히 없는지라 항상 BOJ에 질문하게 되네요..! 

BOJ 코더분들 항상 질문글 올릴때마다 답변 잘 해주셔서 감사합니다 ㅠㅠ 


godmoon00   6년 전

저도 가방끈이 길진 않지만 그나마 아는 선에서 답해 드리겠습니다. 틀린 부분이 있다면 다른 분께서 지적해주시면 감사하겠습니다.

1) 

auto 는 int, bool, char 처럼 변수를 선언할 때 사용하는 것입니다. 다만 auto는 들어갈 타입을 컴파일러가 알아서 예상해서 변수타입을 지정해 줍니다.

예를 들어 auto a = 1; 이라 하면 int a = 1;과 같은 것이죠. (컴파일러에 따라 다를지도 모르겠습니다.)

auto는 보통 변수타입이 길고, 읽기가 불편하고, 또 들어가는 값의 타입이 확실히 정해질 수 있을 때 많이 쓰입니다.

님께서 auto next의 의미를 모르는 이유는 range based for 개념을 몰라서 그렇지 않을까 싶습니다.

vector 같은 컨테이너의 원소를 순회하는 방법은 두가지가 있습니다. 첫번째는 일반적인 방법으로, 아래와 같이 할 수 있습니다.

vector<int> v = {10, 20, 30, 40};
for (int i=0; i<v.size(); i++) {
    cout << v[i] << ' ';  // 실행결과: 10 20 30 40
}

하지만 range based for을 이용하면 훨씬 간단해집니다.

vector<int> v = {10, 20, 30, 40};
for (int i: v) {
    cout << i << ' ';  // 실핼결과: 10 20 30 40
}

이렇게 컨테이너의 원소를 순차적으로 순회하는 것이 range based for 입니다. int i: v 부분의 int는 v가 int형의 벡터이기 떄문입니다.

하지만 만약 좀더 복잡한 형태의 벡터이면 어떨까요?

예를 들어

vector<pair<int, int>> v

를 range based for문으로 순회하고 싶다고 해봅시다.

그러면 아래와 같이 써야 합니다.

for (pair<int, int> i: v) {
    cout << i.first << ' ' << i.second << '\n';
}

음...뭔가 깔끔하지 않고 항상 이렇게 쓰기가 귀찮을 것 같네요.

하지만 위에서 배운 auto를 이용한다면, v의 원소들은 pair<int, int> 임을 알고 있으니 컴파일러가 이를 예측할 수 있습니다.

for (auto i: v) {
    cout << i.first << ' ' << i.second << '\n';
}

그래서 이렇게 쓸 수 있답니다! 훨씬 깔끔해지죠. 그리고 int형 vector를 순회할때와 코드가 비슷해요!

무튼 그래서, 질문으로 돌아오자면 첨부해주신 코드의 벡터는 vector<vector<pair<ll, ll>>> 이라고 하셨는데 거기서 here 번째의 원소는 vector<pair<ll, ll>> 형이 될 것이고 next는 그 벡터 안에 있는 pair<ll, ll> 형의 원소들 하나하나가 되는 것입니다.

(참고로 auto는 c++11 부터 생긴 기능입니다.)


2)

pair로 이루어진 벡터나 큐 같은 컨테이너에 새로운 원소를 집어 넣는 방법은 제가 알기론 3가지가 있습니다. 예를들어 vector<pair<int, int>> v 라는 벡터에 {1, 1}을 넣고 싶다면,

  • v.push_back(pair<int, int>(1, 1)
  • v.push_back(make_pair(1, 1))
  • v.push_back({1, 1})

뭐 개인적인 취향이겠지만....가장 간단한 형태인 세번째 방법을 굳이 안 쓸 이유가 있을까요..? 저는 항상 세번째 방법으로 사용합니다.

vector<vector<pair<ll, ll>>> v 이런 벡터를 첫번째 방법으로 푸쉬를 하고 싶다면... v.push_back({pair<ll, ll>(a, b)}); 이렇게 하시면 될것 같습니다.

다른 방법으로는 v.push_back({make_pair(a, b)}); v.push_back({{a, b}}); 이렇게 하셔도 되고요.


3)

for (for i=0; i<v[here].size(); i++) {
    if (d[v[here][i].first][min(minl,l[v[here][i].first])] != -1)continue;
    pq.push(pair<ll, pair<ll, ll>>(-cost - v[here][i].second * minl, pair<ll, ll>(v[here][i].first, min(minl, l[v[here][i].first]))));
}

네...코드가 끔찍하죠..? 맞는지도 모르겠습니다. 이런 코드 디버깅하기가 쉬울까요... 그냥 range based for 쓰시고 pair는 {}로 푸쉬하시기 바랄게요..

kyaryunha   6년 전

오오 range based for란 개념 처음 알았습니다....!! ((알려주셔서 감사합니다))

헉ㄱ... 그냥ㅇ warning 뜨는거 보면서 살더라도 저도 앞으로 {} 써야겠군요+ㅁ+..!!

그리고 길고 상세하게 설명해주셔서 감사합니다 ㅠㅡㅜㅡ.. 

덕분에 그토록 네이버 검색창 돌아다녀도 이해 안됬었는데 이해됬습니다..!! 

(( 백준 왜케 천사분들 많으신거죠 ㅠㅡㅜㅡ.. 최곱니다))

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