Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[정렬] 3월 7일 #1

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions 03월_04일-정렬/1026.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 테스트 결과는 똑같이 나왔으나 백준에선 틀렸다고 나옴

void minS(vector<int> &a, vector<int> &b, int n)
{
//가장 작은 값과 가장 큰 값을 곱하면 최솟값이 나오지 않을까?
//그 다음 작은 값과 그 다음 큰 값을 만나도록 짜려면?
// a를 오름차순으로 정렬한 뒤 b의 가장 큰 값의 인덱스를 찾아 a의 첫 번째 원소부터 짝을 맺게 하면 되지 않을까?
Comment on lines +11 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우선 생각해 주신 아이디어는 완전 맞습니다! 😊 사실 해당 문제는 O(N) 으로 풀 수 있지만 현재 코드에서 반례를 알려드릴께요! 지금 b의 가장 큰 값을 찾은 후 0으로 만든 후 다음으로 큰 값을 계속 찾아주고 있는데요. 만약 b가 양수라면 해당 풀이로 항상 서로 다른 인덱스의 값에 참조할 수 있을 거예요! 그런데 그렇지 않은 경우엔 어떻게 될까요? 만약 b가 0이 가능하면 무슨 일이 벌어질까요? 문제에서 b가 가능한 범위를 다시 한 번 살펴볼까요! max_index가 항상 다르게 선택이 될지 디버깅해보시면 좋을 것 같아요 😊

vector<int> tmp1 = a;
vector<int> tmp2 = b;
sort(tmp1.begin(), tmp1.end());

int max_a = 0, max_b = 0, max_index = 0, min_index = 0;
int min_a = a[0], min_b = b[0];

for (int i = 0; i < n; i++) // a 원소를 순서대로 바꿈
{
for (int j = 0; j < n; j++) // b의 최댓값을 찾은 후 a와 매칭
{
if (max_b < tmp2[j])
{
max_b = tmp2[j];
max_index = j;

}
}

cout << "max_index : " <<max_index <<"\n";
a[max_index] = tmp1[i];

// b의 조건이 음수가 아닌 정수이므로 음수를 사용해 해당 원소를 사용했음을 알린다.
tmp2[max_index] = -1;
max_b = -1;
Comment on lines +36 to +38
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋아요~! 반례를 찾아 잘 수정해주셨어요! 🤛

사실 이 문제는 지금 보연님께서 생각해주신 아이디어 그대로 O(n)의 시간복잡도로 해결할 수 있어요! B를 재배열 할 순 없다고 했지만, A는 재배열이 가능하니 해당 아이디어 (A의 가장 작은 값 <=> B의 가장 큰 값 계속 매칭) 를 B를 재배열해서 구현할 수 있지 않을까요? 더 자세한 부분은 샘플코드를 참고해주셔도 좋을 것 같아요~!

}

//합 구하기
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += a[i] * b[i];
}

cout << sum;
}

int main()
{
//입력
int n;
cin >> n;

vector<int> a(n);
vector<int> b(n);

for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
cin >> b[i];
}

//연산
minS(a, b, n);
}
41 changes: 41 additions & 0 deletions 03월_04일-정렬/10804.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <iostream>
#include <vector>

using namespace std;

vector<int> card;


void reverse(int a, int b)
{
while (a < b)
{
swap(card[a++], card[b--]);
}
}
Comment on lines +9 to +15
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배열을 역으로 바꾸는 원리를 잘 캐치해서 swap을 활용해 reverse함수를 직접 구현해주셨네요! 아주 좋아요! 샘플코드에선 STL함수를 사용한 풀이도 있으니 참고해보셔도 좋을 것 같아요~! 👍


int main()
{
vector<int> a(10, 0);
vector<int> b(10, 0);

card.assign(20, 0);

for (int i = 0; i<10 ; i++) {
cin >> a[i] >> b[i];
}
Comment on lines +24 to +26
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 배열에 입력 받아서 처리해주신 것도 좋지만, a와 b는 전의 정보를 저장하는 것보단 현재 a와 b가 무엇이고 그것에 따라 연산을 수행하기 때문에 여기서 더 메모리를 아껴도 좋을 것 같아요~!


for (int i = 0; i < 20; i++)
{
card[i] = i + 1;
}

for (int i = 0; i<10 ; i++) {
reverse(a[i] - 1, b[i] - 1);
}

for (int i = 0; i < 20; i++)
{
cout << card[i] << " ";
}
}
39 changes: 39 additions & 0 deletions 03월_04일-정렬/11651.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct coor
{
int x, y;
};
Comment on lines +7 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 구조체 사용도 좋지만 인자가 2개일 경우엔 더 편하게 사용할 수 있는 방법이 있어요! 정렬 피피티에 "이것도 알아보세요" 부분을 참고해 보셔도 좋을 것 같아요 😎


bool cmp(const coor &a, const coor &b){
if (a.y == b.y) {
return a.x < b.x;
}
return a.y < b.y;
}
Comment on lines +12 to +17
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋아요~~! 지금도 좋지만 만약 조건이 많아질 경우 계속 if문 안으로 들어가게 될 거예요! 따라서 같은지를 조건으로 보는 것보다 다른지를 봐주면 앞으로 비교함수 작성에서 코드를 더 깔끔하게 작성하실 수 있을 거예요 😉



int main()
{
int n;
cin >> n;
vector<coor> crd(n);

for (int i = 0; i < n; i++)
{
cin >> crd[i].x >> crd[i].y;
}

//연산
sort(crd.begin(), crd.end(), cmp);

//출력
for (int i = 0; i < n; i++)
{
cout << crd[i].x <<" "<< crd[i].y << "\n";
}
}
56 changes: 56 additions & 0 deletions 03월_04일-정렬/12840.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <iostream>
#include <vector>

using namespace std;

void query(int T, int c, int &total)
{
if (T == 1)
{
total = total + c;
if ( total >= 86400) { //하루가 넘어감
total = total % 86400;
}
}
else if (T == 2)
{
total = total - c;
if ( total < 0){ //전날로 넘어감
total = total % 86400;
total = 86400 + total;
}
}
Comment on lines +15 to +22
Copy link

@bsa0322 bsa0322 Mar 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p1. 모듈러 연산을 사용해야 한다는 걸 아주 잘 파악해 주셨어요!!! 하루가 넘어간 부분에 대한 연산은 지금 아주 잘 이루어지고 있어요. 다만 전날로 넘어간 경우에 대해 반례가 하나 있는데요!
지금 0 이하인 경우에 모듈러 연산을 해주고, 무조건 하루를 더해주고 있죠! 기본 로직은 거의 맞아요! 하지만 만약, 정확히 하루 전으로 돌아간 경우엔 어떻게 될까요? 지금대로라면, 우선 18번째 조건에 걸려서 모듈러 연산을 해줄텐데 정확히 하루 전이라면 total 값이 -86400 인 거니까 ...!?
진짜 거의 다 왔어요!! 힌트 더 필요하다면 말씀해주세요~!

else
{
int h_ = total / 3600;
int m_ = total % 3600 / 60;
int s_ = total % 3600 % 60;
cout << h_ << " " << m_ << " " << s_ << "\n";
Comment on lines +25 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. 자주 쓰는 60, 3600은 상수로 선언하고 사용해도 좋을 것 같아요~! 그럼 가독성도 높아지고 실수할 일이 줄어들 거예요 😊 더불어 출력은 되도록 main에서 해주시는 게 좋아요! 함수에서의 출력은 디버깅용이 아닌 이상, 나중에 함수가 많아졌을 때 헷갈리기 쉬워질 수 있어요. 함수를 만들어주신 것도 너무 좋지만, 출력이 필요하다면 모두 메인에서 처리해주는 것도 좋을 것 같아요~!

}
}

int main()
{
//현재 시간
int h, m, s, total;
cin >> h >> m >> s;

total = h * 3600 + m * 60 + s;

//쿼리 개수
int q;
cin >> q;

//쿼리
int T, c;
for (int i = 0; i < q; i++)
Comment on lines +45 to +46
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. i의 값을 쓸 필요가 없고, q값을 다시 사용하지 않으므로 이럴 땐 while(q--)로 입력을 받으면 깔끔하게 받을 수 있어요~~!

{
cin >> T;
if (T != 3)
{
cin >> c;
query(T, c, total);
}
query(T, 0, total);
}
}
43 changes: 43 additions & 0 deletions 03월_04일-정렬/1758.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// N <= 100,000 (자연수)
// tip <= 100,000 (자연수)

//최댓값을 가정해보면 약 150억이 나온다. (맞나요..?)
//int형은 signed int형일 경우 20억(unsigned int는 40억)까지밖에 표현을 못하기 때문에 long long 타입을 사용해야 한다.
Comment on lines +10 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞아요~~!! 정확히는 최댓값을 가정해보면 1 ~ 100000 를 모두 더한 값으로 약 50억이 나와요!! 😉
11번째 줄에 써주신 주석은 정확히 맞습니다~! 아주 좋아요 😎

앞으로 항상 문제 풀어주실 때, 맞게 푼 거 같은데 안 풀린다면 자료형의 범위를 넘어가진 않는지 확인해주는 게 좋습니다!

long long maxTip(int n, vector<int> &tip)
{
int t;
long long max = 0;
for (int i = 0; i < n; i++)
{
t = tip[i] - i;
if (t < 0)
{
t = 0;
}

max += t;
Comment on lines +18 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p3. tip은 이미 내림차순 정렬이 된 상태이네요! 한 번 t 값이 음수라면 그 이후는 어떻게 될까요? 연산을 더 줄일 수 있어 보여요~!

}
return max;
}

int main()
{
int n;
cin >> n;

vector<int> tip(n, 0);
for (int i = 0; i < n; i++)
{
cin >> tip[i];
}

//연산
sort(tip.begin(), tip.end(), greater<>());
Comment on lines +40 to +41
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1등인 사람이 가장 팁이 많을수록 강호가 받는 팁이 많아진다는 걸 아주 잘 파악해주셨네요~! 좋아요 👍

cout << maxTip(n, tip);
}