[C++] 10825 국영수

cherry_·2023년 10월 10일
0

코딩테스트 준비

목록 보기
3/15

정답

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//국어 내림차순. 같으면 아래로
//영어 오름차순. 같으면 아래로
//수학 내림차순. 같으면 아래로.
//이름 오름차순. (아스키 코드 사용)

vector<string> name;
    
bool compare(vector<int> &v1, vector<int> &v2){
    if(v1[1] == v2[1]){ 
        if(v1[2] == v2[2]){
            if(v1[3] == v2[3]){
                return name[v1[0]] < name[v2[0]];
            }
            return v1[3] > v2[3];
        }
        return v1[2] < v2[2];
    }
    return v1[1] > v2[1];
}


int main()
{
    int t;
    vector<vector<int>> score;
    
    cin >> t;
    
    for(int i=0; i<t; i++){
        string n;
        int a, b, c;
        cin >> n >> a >> b >> c;
        name.push_back(n);      //이름 저장
        score.push_back({i, a, b, c});  //
    }
    
    sort(score.begin(), score.end(), compare);
    for(int i=0; i<t; i++){
        cout << name[score[i][0]] << "\n";
    }
    
    return 0;
}

1차 코드

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

//국어 내림차순. 같으면 아래로
//영어 오름차순. 같으면 아래로
//수학 내림차순. 같으면 아래로.
//이름 오름차순. (아스키 코드 사용)

bool compare(vector<int> &v1, vector<int> &v2){
    if(v1[1] == v2[1]){ 
        if(v1[2] == v2[2]){
            if(v1[3] == v2[3]){
                return v1[4] < v2[4];
            }
            return v1[3] > v2[3];
        }
        return v1[2] < v2[2];
    }
    return v1[1] > v2[1];
}


int main()
{
    int t;
    vector<string> name;
    vector<vector<int>> score;
    
    cin >> t;
    
    for(int i=0; i<t; i++){
        string n;
        int a, b, c;
        cin >> n >> a >> b >> c;
        name.push_back(n);      //이름 저장
        score.push_back({i, a, b, c});  //
    }
    
    sort(score.begin(), score.end(), compare);
    for(int i=0; i<t; i++){
        cout << name[score[i][0]] << "\n";
    }
    
    return 0;
}

크게 문제가 없어 보이는데 자꾸 HaebinJunkyu이 바뀌어서 나온다.
Junkyu 50 60 100
Haebin 50 60 100
둘의 입력값은 위와 같기에 사전순 정렬에 문제가 있어 보였다.
하지만.....

return s1.name < s2.name; // (국어, 영어, 수학 점수가 같으면) 이름이 사전 순으로 증가하는 순서

찾다 못해 본 예시 답안도 나랑 똑같이 부등호를 넣었는데 뭐가 문제지?

해결

ㅋㅋ...
그냥 내가 바보였다.
구조체 쓰는 방법이 기억이 안 나서 (...) 이름과 성적을 서로 다른 벡터에 넣었는데 이름 벡터를 비교하지 않고 있지도 않은 값을 비교하고 있었으니 정렬이 안 될 수 밖에...
없는 값을 조회했는데 에러가 안 나고 00 으로 떠서 00 과 00 값을 비교하고 있었다.

return name[v1[0]] < name[v2[0]];

vector<string> name;을 전역으로 돌리고 이렇게 바꿔서 해결!

기억할 point

  1. 2차원 벡터의 사용자 정의 sort
    내가 쓴 벡터는 vector<vector<int>>
  • bool compare()
  • bool compare(vector<int> &v1, vector<int> &v2)
    - 내부의 벡터를 주소값으로 받아서 넣는다.
  • sort(score.begin(), score.end(), compare);
    - compare() 아님! 괄호 빼고 쓰기.
  1. 이름 오름차순. (아스키 코드 사용)
    따로 처리해줄 필요 없다. -'A' 이런거 해야하나 했는데.
    부등호로 충분히 처리할 수 있다.

  2. 조건문에는 '해당하는 값'을 넣는 것보다 '예외일 때'를 조건으로 넣는 게 더 좋을 것 같다.

아래 참고. (by.튜터님들 감사합니다..)

// 비교 함수(bad)
bool cmp(const student& s1, const student& s2) {
	if (s1.kor == s2.kor) { // 국어 점수가 같으면
		if (s1.eng == s2.eng) { // 국어, 영어 점수가 같으면
			if (s1.math == s2.math) { // 국어, 영어, 수학 점수가 같으면 
				return s1.name < s2.name; // 이름이 사전 순으로 증가하는 순서
			}
			return s1.math > s2.math; // 수학 점수가 감소하는 순서
		}
		return s1.eng < s2.eng; // 영어 점수가 증가하는 순서
	}
	return s1.kor > s2.kor; // 국어 점수가 감소하는 순서
}

// 비교 함수(good)
bool cmpAdv(const student& s1, const student& s2) {
	if (s1.kor != s2.kor) {// 국어 점수가 감소하는 순서
		return s1.kor > s2.kor;
	}
	if (s1.eng != s2.eng) {// (국어 점수가 같으면) 영어 점수가 증가하는 순서
		return s1.eng < s2.eng;
	}
	if (s1.math != s2.math) {// (국어, 영어 점수가 같으면) 수학 점수가 감소하는 순서
		return s1.math > s2.math;
	}
	return s1.name < s2.name; // (국어, 영어, 수학 점수가 같으면) 이름이 사전 순으로 증가하는 순서
}

참고한 블로그

링크텍스트

0개의 댓글