https://school.programmers.co.kr/learn/courses/30/lessons/42840
뭔가 이렇게 길게 작성하지 않아도 될것 같은 느낌이 들었지만, 떠오르는 방식이 아래와 같아서 아래와 같이 구현했다.
#include <bits/stdc++.h>
using namespace std;
int math3(vector<int>& v){
int cnt=0;
for(int i=0; i<v.size();i++){
int a=i%10;
switch(a){
case 0: if(v[i]==3) cnt++;
break;
case 1: if(v[i]==3) cnt++;
break;
case 2: if(v[i]==1) cnt++;
break;
case 3: if(v[i]==1) cnt++;
break;
case 4: if(v[i]==2) cnt++;
break;
case 5: if(v[i]==2) cnt++;
break;
case 6: if(v[i]==4) cnt++;
break;
case 7: if(v[i]==4) cnt++;
break;
case 8: if(v[i]==5) cnt++;
break;
case 9: if(v[i]==5) cnt++;
break;
}
}
return cnt;
}
int math2(vector<int>& v){
int cnt=0;
for(int i=0; i<v.size();i++){
int a=i%8;
switch(a){
case 0: if(v[i]==2) cnt++;
break;
case 1: if(v[i]==1) cnt++;
break;
case 2: if(v[i]==2) cnt++;
break;
case 3: if(v[i]==3) cnt++;
break;
case 4: if(v[i]==2) cnt++;
break;
case 5: if(v[i]==4) cnt++;
break;
case 6: if(v[i]==2) cnt++;
break;
case 7: if(v[i]==5) cnt++;
break;
}
}
return cnt;
}
int math1(vector<int>& v){
int cnt=0;
for(int i=0; i<v.size();i++){
int a=i%5;
switch(a){
case 0: if(v[i]==1) cnt++;
break;
case 1: if(v[i]==2) cnt++;
break;
case 2: if(v[i]==3) cnt++;
break;
case 3: if(v[i]==4) cnt++;
break;
case 4: if(v[i]==5) cnt++;
break;
}
}
return cnt;
}
bool cmp(pair<int,int> p,pair<int,int> q){
return p.first>q.first || p.second<q.second;
}
vector<int> solution(vector<int> v) {
vector<int> answer;
int a= math1(v);
int b= math2(v);
int c= math3(v);
auto p = make_pair(a,1);
auto q = make_pair(b,2);
auto r = make_pair(c,3);
vector<pair<int,int>> tmp;
tmp.push_back(p);
tmp.push_back(q);
tmp.push_back(r);
sort(tmp.begin(),tmp.end(),cmp);
for(auto t: tmp){
cout<<t.first<<" : "<<t.second<<'\n';
}
for(int i=0; i<tmp.size(); i++) {
if(i==0) answer.push_back(tmp[i].second);
else{
if(tmp[i].first==tmp[0].first) answer.push_back(tmp[i].second);
}
}
return answer;
}
/*
1 2 3 4 5 || 1 2 3 4 5 || ...
2 1 2 3 2 4 2 5 || 2 1 2 3 2 4 2 5 || ...
3 3 1 1 2 2 4 4 5 5 || 3 3 1 1 2 2 4 4 5 5 || ...
*/
처음에, pair 끼리의 비교에서 first는 내림차순으로, second드는 오름차순으로 비교하는 함수를 cmp 함수로 만들어서 제공할때,
bool cmp(pair<int,int> p,pair<int,int> q){
return p.first>q.first && p.second<q.second;
}
로 만들어서 제출했는데, 예제 케이스의 경우는 통과하는데 제출하니까 틀려서 고민을 많이했다.
그러다가 입력 : [1, 1, 1, 1, 1] // 출력: [3] 으로 놓고 해보았을때,
1: 1
1: 2
2: 3
형태로 잘못된 순서로 정렬되는 것을 보고 cmp 함수를 수정해서,
bool cmp(pair<int,int> p,pair<int,int> q){
return p.first>q.first || p.second<q.second;
}
이와같이 수정해서 제출해서 통과할 수 있었다.
아직 cmp 함수를 만들때, pair의 비교에서, first와 second가 반대방향으로 정렬되도록 하는것을 할줄 모르는것 같다.
위와 같은 상황에서 어떤식으로 compare 함수를 작성해야 옳은지 gpt 검색을 통해 모범 예시안을 요구해보았다.
`std::sort` 함수를 사용할 때, 사용자 정의 비교 함수를 만들어 pair의 요소를 내림차순으로 정렬하려면 다음과 같이 할 수 있습니다. 아래 예제에서는 `first`를 내림차순으로 정렬하고, `second`를 오름차순으로 정렬하도록 구현한 compare 함수를 보여줍니다.
#include <iostream>
#include <vector>
#include <algorithm>
// 비교 함수를 정의합니다.
bool customCompare(const std::pair<int, int>& a, const std::pair<int, int>& b) {
// 먼저 first를 내림차순으로 정렬합니다.
if (a.first > b.first) {
return true;
}
else if (a.first < b.first) {
return false;
}
// 만약 first가 같으면 second를 오름차순으로 정렬합니다.
return a.second < b.second;
}
int main() {
std::vector<std::pair<int, int>> pairs = {{1, 3}, {2, 2}, {1, 2}, {2, 1}};
// compare 함수를 사용하여 pairs를 정렬합니다.
std::sort(pairs.begin(), pairs.end(), customCompare);
for (const auto& pair : pairs) {
std::cout << "(" << pair.first << ", " << pair.second << ") ";
}
return 0;
}
이 코드에서 `customCompare` 함수는 `std::pair<int, int>` 타입의 두 pair를 비교합니다. 먼저 `first` 요소를 내림차순으로 비교하고, 만약 `first` 요소가 같다면 `second` 요소를 오름차순으로 비교합니다. 이렇게하면 `first`가 내림차순으로, `second`가 오름차순으로 정렬된 결과를 얻을 수 있습니다.
재미있는 점은, 내가 작성한 compare 함수에 대한 분석과 올바른 compare 함수를 찾아달라고 하니까,
완전히 잘못된 결과를 도출했다.
실질적으로 두번째 cmp2가 원하는 결과를 가져다주는 올바른 동작을 한다.
첫번째의 경우는 두가지 경우를 모두 만족하는 경우여야만 true를 return 하는데, 그 경우는 몇가지 경우들중에서 딱 특정한 경우이므로, 가능한 경우가 굉장히 적은 케이스인데, 그게 아닌 경우는 그냥 지나쳐 버리면서 정렬이 이루어지지 않는 형태로 sort()가 수행된다.
정렬하기 전과, 정렬한 후에 대한 비교를 하기 위해서 개별 원소들을 출력해보면 결과물이,
이런식으로 정렬이 이루어지지 않고 그대로 나오게 된다.
cmp2가 정렬이 제대로 이루어진다.
**gpt3.5 의 말을 너무 완벽하다고 생각하지 말자.**
대신에,
bool cmp(const std::pair<int, int>& a, const std::pair<int, int>& b) {
// 먼저 first를 내림차순으로 정렬합니다.
if (a.first > b.first) {
return true;
}
else if (a.first < b.first) {
return false;
}
// 만약 first가 같으면 second를 오름차순으로 정렬합니다.
return a.second < b.second;
}
이렇게 제시해준 cmp 함수의 경우 아주 잘 작동한다.
물론 내가 작성한 것처럼 a.first>b.first || a.second<b.second 로 작성해서 할수도 있겠으나,
오히려 gpt에서 제시해준 것처럼 명료하게 경우들을 나누어서 결과물이 도출되도록 하는것이 좋을것 같다.
bool cmp(pair<int,int> a, pair<int,int> b){
if(a.first>b.first) return true;
else if(a.first<b.first) return false;
return a.second<b.second;
}
형태를 잘 이해하고 기억하고 있다가, 다음에도 이런식으로 첫번째 원소와 두번째 원소를 정 반대로 정렬해야 할때 잘 이용해보도록 하자.
위의 형태에서,
bool cmp(pair<int,int> a, pair<int,int> b){
if(a.first>b.first) return true;
else if(a.first<b.first) return false;
else return a.second<b.second;
}
처럼 맨 마지막에 else를 하더라도 동일한 결과를 제공한다.
++++++++++++++++++++++
마지막으로, 다른 사람의 풀이를 첨부해보겠다.
내 풀이의 경우 생각난 풀이가 저거라 뭔가 더 깔끔하게 구현할 수 있을것 이라는걸 알면서도 일단 저렇게 구현을 해서 통과를 했는데, 정말 간결하게 작성할 수 있는 풀이들이 많은것 같다.
가장 좋아요를 많이 받은 코드의 경우 아래의 코드이다.
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> one = {1,2,3,4,5};
vector<int> two = {2,1,2,3,2,4,2,5};
vector<int> thr = {3,3,1,1,2,2,4,4,5,5};
vector<int> solution(vector<int> answers) {
vector<int> answer;
vector<int> they(3);
for(int i=0; i<answers.size(); i++) {
if(answers[i] == one[i%one.size()]) they[0]++;
if(answers[i] == two[i%two.size()]) they[1]++;
if(answers[i] == thr[i%thr.size()]) they[2]++;
}
int they_max = *max_element(they.begin(),they.end());
for(int i = 0; i< 3; i++) {
if(they[i] == they_max) answer.push_back(i+1);
}
return answer;
}
아래의 코드도 정말 보기에 편하고 깔끔하다.
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
vector<int> solution(vector<int> answers) {
vector<int> answer;
int one[5] = {1, 2, 3, 4, 5};
int two[8] = { 2, 1, 2, 3, 2, 4, 2, 5};
int three[10] = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5};
int a = 0, b = 0, c = 0; //1, 2, 3번 수포자가 맞춘 개수
int i = 0; //문제의 번호
while(answers.size() != i){
if(answers[i] == one[i % 5])
a++;
if(answers[i] == two[i % 8])
b++;
if(answers[i] == three[i % 10])
c++;
i++;
}
int result = max(max(a, b), c);
if(result == a)
answer.push_back(1);
if(result == b)
answer.push_back(2);
if(result == c)
answer.push_back(3);
return answer;
}
결국 둘다 같은 로직을 사용했다고 볼 수 있는데, 나와의 차이점은 주어지는 수들을 vector로 담아서 이 vector 를 사용하는 형태로 코드를 작성했기 때문에 훨씬 간결하게 표현할 수 있었다는 것이다. 아주아주 멋지다. 다음에도 이와같이 수들이 사이즈가 다르게 여러 케이스들이 주어진다면 vector에 담아서 한번 사용해보도록 하자.
'알고리즘 > 프로그래머스' 카테고리의 다른 글
프로그래머스 lv 2. 42842 카펫 c++ (0) | 2023.11.08 |
---|---|
프로그래머스 lv 2. 42839 소수찾기 c++ (0) | 2023.11.08 |
프로그래머스 lv 1. 86491 c++ 최소직사각형 (0) | 2023.11.01 |
프로그래머스 lv 2. 42747 c++ H-index (0) | 2023.10.31 |
프로그래머스 lv 2. 42746 c++ 가장 큰 수 (0) | 2023.10.31 |