0. 개요
오늘은 언리얼에서 새롭게 배운것 보다는 배운걸 복습 한다는 개념으로 해서 따로 기록할 만한 것은 없었다.
대신 코딩 테스트 연습 문제 풀면서
그냥 문제를 푸는게 목표가 아닌 언리얼로 게임을 만든다 생각하고
클래스를 사용해봤는데 생각 보다 시간 복잡도가 높지 않았었다
나는 클래스를 생성해주는 과정에서도 시간이 많이 늘었을 거라 생각했는데 그건 아니였나보다
1. 문제 내용
점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번호의 학생이나 바로 뒷번호의 학생에게만 체육복을 빌려줄 수 있습니다. 예를 들어, 4번 학생은 3번 학생이나 5번 학생에게만 체육복을 빌려줄 수 있습니다. 체육복이 없으면 수업을 들을 수 없기 때문에 체육복을 적절히 빌려 최대한 많은 학생이 체육수업을 들어야 합니다.
전체 학생의 수 n, 체육복을 도난당한 학생들의 번호가 담긴 배열 lost, 여벌의 체육복을 가져온 학생들의 번호가 담긴 배열 reserve가 매개변수로 주어질 때, 체육수업을 들을 수 있는 학생의 최댓값을 return 하도록 solution 함수를 작성해주세요.
제한사항
- 전체 학생의 수는 2명 이상 30명 이하입니다.
- 체육복을 도난당한 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
- 여벌의 체육복을 가져온 학생의 수는 1명 이상 n명 이하이고 중복되는 번호는 없습니다.
- 여벌 체육복이 있는 학생만 다른 학생에게 체육복을 빌려줄 수 있습니다.
- 여벌 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다. 이때 이 학생은 체육복을 하나만 도난당했다고 가정하며, 남은 체육복이 하나이기에 다른 학생에게는 체육복을 빌려줄 수 없습니다.
1. 학생들이 체육복을 도난당한 상황이다
2. 여벌의 체육복을 가지고 있던 학생도 있지만 그중 하나가 도난 당했을 수도 있다.
3. 여벌의 체육복을 빌려줄수있는 건 1번 뿐이다.
4. 양옆의 학생들에게 간섭 할수 있다.
이러한 조건에서 시작했다.
#include <string>
#include <vector>
#include <map>
using namespace std;
//클래스 구현해도되는 지모르지만 클래스 구현해보자
//reserve의 학생과 로스트 학생을 가져와야겠다.
class Student
{
private:
int Number;
int count;
public:
Student(int Num) : Number(Num), count(1) {}
const int GetCount()
{
return count;
}
bool IsZero()
{
return count == 0;
}
bool IsSpare() {
return count == 2;
}
void Lost() {
count = (count - 1) > 0 ? count - 1 : 0;
}
void Plus() {
count++;
}
void Reserve(Student& num1)
{
if (count <= 1)
{
return;
}
if (num1.count == 0)
{
num1.Plus();
this->Lost();
return;
}
}
void Reserve(Student& num1, Student& num2 )
{
if (count <= 1)
{
return;
}
if (num1.count == 0)
{
num1.Plus();
this->Lost();
return;
}
if (num2.count == 0)
{
num2.Plus();
this->Lost();
return;
}
}
};
int solution(int n, vector<int> lost, vector<int> reserve) {
int answer = 0;
map<int, Student> StudentClass;
for (int i = 1; i <= n; i++)
{
StudentClass.insert({ i, Student(i) });
}
for (int num : lost)
{
//벡터에서 찾지않고 map으로 탐색
if (StudentClass.find(num) == StudentClass.end())
{
//잃어버림
StudentClass[num].Lost();
}
}
for (int num : reserve)
{
//벡터에서 찾지않고 map으로 탐색
if (StudentClass.find(num) == StudentClass.end())
{
StudentClass[num].Plus();
}
}
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
StudentClass[i].Reserve(StudentClass[i + 1]);
}
else if (i == (n - 1))
{
StudentClass[i].Reserve(StudentClass[i - 1]);
}
else {
StudentClass[i].Reserve(StudentClass[i - 1], StudentClass[i + 1]);
}
}
for (int i = 1; i <= n; i++)
{
if (StudentClass[i].IsZero() == false)
{
answer++;
}
}
return answer;
}
먼저 학생 클래스를 만들어서 체육복 개수를 가지게 해주었다.
그리고 최근에 알게된 빠른 탐색을 위해서는 벡터보다 맵을 사용하라는 것을 배웠던 경험으로
맵을 사용해보았다.
해당 코드에서 오류가 발생하길래 무언가 해서 알아보니
이유는 Student() 의 기본 생성자를 안만들어줘서였다..
그리고 조건도 이상한게 있어서 아래 문제가 생겼다
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <map>
using namespace std;
//클래스 구현해도되는 지모르지만 클래스 구현해보자
//reserve의 학생과 로스트 학생을 가져와야겠다.
class Student
{
private:
int Number;
int count;
public:
Student() : Number(0), count(1) {} // 기본 생성자 추가
Student(int Num) : Number(Num), count(1) {}
const int GetCount()
{
return count;
}
bool IsZero()
{
return count == 0;
}
bool IsSpare() {
return count == 2;
}
void Lost() {
count = (count - 1) > 0 ? count - 1 : 0;
}
void Plus() {
count++;
}
void Reserve(Student& num1)
{
if (count <= 1)
{
return;
}
if (num1.count == 0)
{
num1.Plus();
this->Lost();
return;
}
}
void Reserve(Student& num1, Student& num2 )
{
if (count <= 1)
{
return;
}
if (num1.count == 0)
{
num1.Plus();
this->Lost();
return;
}
if (num2.count == 0)
{
num2.Plus();
this->Lost();
return;
}
}
};
int solution(int n, vector<int> lost, vector<int> reserve) {
int answer = 0;
map<int, Student> StudentClass;
for (int i = 1; i <= n; i++)
{
StudentClass.insert({ i, Student(i) });
}
for (int num : lost)
{
//벡터에서 찾지않고 map으로 탐색
if (StudentClass.find(num) != StudentClass.end())
{
//잃어버림
StudentClass[num].Lost();
}
}
for (int num : reserve)
{
//벡터에서 찾지않고 map으로 탐색
if (StudentClass.find(num) != StudentClass.end())
{
StudentClass[num].Plus();
}
}
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
StudentClass[i].Reserve(StudentClass[i + 1]);
}
else if (i == (n - 1))
{
StudentClass[i].Reserve(StudentClass[i - 1]);
}
else {
StudentClass[i].Reserve(StudentClass[i - 1], StudentClass[i + 1]);
}
}
for (int i = 1; i <= n; i++)
{
if (StudentClass[i].IsZero() == false)
{
answer++;
}
}
return answer;
}
int main() {
int n;
vector<int> lost;
vector<int> reserve;
n = 30;
lost = { 28 ,30 };
reserve = { 27,29 };
int result = solution(n,lost,reserve);
cout << result;
return 0;
}
map에서 탐색 하기위해 == 를 사용했었는데 아직 실력미숙으로 ==이 포함인 것 인줄 알고 상요했으나
!= 로 해줘서 포함되어있는지 확인하게 해주었다
그러나 무언가 다른 예제에서 실패했다 21 23 25번 문제에서 실패해서
질문하기에서 누군가의 답변이 n = 30, lost 28 30, reserve 27 29 이 문제를 풀었을때
답이 30이 나와야 한다고 했다.
하지만 내 코드는 29가 나왔다.
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
StudentClass[i].Reserve(StudentClass[i + 1]);
}
else if (i == (n - 1))
{
StudentClass[i].Reserve(StudentClass[i - 1]);
}
else {
StudentClass[i].Reserve(StudentClass[i - 1], StudentClass[i + 1]);
}
}
디버그 모드로 찾아보니 29번에 else if 문이 잘못 되었단걸 확인했다. n <= 으로 해놨는데 조건을 n -1 로 해버려서 끝번호가아닌 그 전 번호로 해놨던 거였다.
제출 코드
#include <string>
#include <vector>
#include <map>
using namespace std;
//클래스 구현해도되는 지모르지만 클래스 구현해보자
//reserve의 학생과 로스트 학생을 가져와야겠다.
class Student
{
private:
int Number;
int count;
public:
Student() : Number(0), count(1) {} // 기본 생성자 추가
Student(int Num) : Number(Num), count(1) {}
const int GetCount()
{
return count;
}
bool IsZero()
{
return count == 0;
}
bool IsSpare() {
return count == 2;
}
void Lost() {
count = (count - 1) > 0 ? count - 1 : 0;
}
void Plus() {
count++;
}
void Reserve(Student& num1)
{
if (count <= 1)
{
return;
}
if (num1.count == 0)
{
num1.Plus();
this->Lost();
return;
}
}
void Reserve(Student& num1, Student& num2 )
{
if (count <= 1)
{
return;
}
if (num1.count == 0)
{
num1.Plus();
this->Lost();
return;
}
if (num2.count == 0)
{
num2.Plus();
this->Lost();
return;
}
}
};
int solution(int n, vector<int> lost, vector<int> reserve) {
int answer = 0;
map<int, Student> StudentClass;
for (int i = 1; i <= n; i++)
{
StudentClass.insert({ i, Student(i) });
}
for (int num : lost)
{
//벡터에서 찾지않고 map으로 탐색
if (StudentClass.find(num) != StudentClass.end())
{
//잃어버림
StudentClass[num].Lost();
}
}
for (int num : reserve)
{
//벡터에서 찾지않고 map으로 탐색
if (StudentClass.find(num) != StudentClass.end())
{
StudentClass[num].Plus();
}
}
for (int i = 1; i <= n; i++)
{
if (i == 1)
{
StudentClass[i].Reserve(StudentClass[i + 1]);
}
else if (i == n )
{
StudentClass[i].Reserve(StudentClass[i - 1]);
}
else {
StudentClass[i].Reserve(StudentClass[i - 1], StudentClass[i + 1]);
}
}
for (int i = 1; i <= n; i++)
{
if (StudentClass[i].IsZero() == false)
{
answer++;
}
}
return answer;
}
문제를 수정하고 제출 한 코드이다 for문을 평소보다 많이 사용했는데
시간은 괜찮게 나왔다
테스트 1 〉 | 통과 (0.02ms, 4.12MB) |
테스트 2 〉 | 통과 (0.01ms, 4.11MB) |
테스트 3 〉 | 통과 (0.01ms, 4.13MB) |
테스트 4 〉 | 통과 (0.01ms, 4.17MB) |
테스트 5 〉 | 통과 (0.01ms, 4.12MB) |
테스트 6 〉 | 통과 (0.01ms, 4.2MB) |
테스트 7 〉 | 통과 (0.01ms, 4.2MB) |
테스트 8 〉 | 통과 (0.01ms, 4.21MB) |
테스트 9 〉 | 통과 (0.02ms, 4.27MB) |
테스트 10 〉 | 통과 (0.01ms, 3.62MB) |
테스트 11 〉 | 통과 (0.01ms, 4.13MB) |
테스트 12 〉 | 통과 (0.01ms, 4.17MB) |
테스트 13 〉 | 통과 (0.01ms, 4.21MB) |
테스트 14 〉 | 통과 (0.01ms, 4.21MB) |
테스트 15 〉 | 통과 (0.01ms, 4.16MB) |
테스트 16 〉 | 통과 (0.01ms, 4.15MB) |
테스트 17 〉 | 통과 (0.01ms, 4.2MB) |
테스트 18 〉 | 통과 (0.01ms, 4.2MB) |
테스트 19 〉 | 통과 (0.01ms, 4.16MB) |
테스트 20 〉 | 통과 (0.01ms, 4.15MB) |
테스트 21 〉 | 통과 (0.01ms, 4.21MB) |
테스트 22 〉 | 통과 (0.01ms, 4.21MB) |
테스트 23 〉 | 통과 (0.01ms, 4.13MB) |
테스트 24 〉 | 통과 (0.01ms, 4.21MB) |
테스트 25 〉 | 통과 (0.02ms, 4.19MB) |
테스트 26 〉 | 통과 (0.01ms, 4.11MB) |
테스트 27 〉 | 통과 (0.01ms, 3.67MB) |
테스트 28 〉 | 통과 (0.01ms, 4.13MB) |
테스트 29 〉 | 통과 (0.01ms, 3.67MB) |
테스트 30 〉 | 통과 (0.01ms, 4.13MB) |
클래스도 사용하고 for문도 많았는데 괜찮게 나왔다는게 신기했고 신기한만큼
아 난 아직 제대로 공부한 게아닌가 아니면 새롭게 배워간건가 싶은 생각이 들었다.
언리얼 이야기
만들어봤던 연습 캐릭터, 게임모드, UI를 전부 다시 만들어 보고 있는데
나는 따라해서 만드는 것보다 분석 하면서 배우는 과정에서 더 공부가 잘된 것 같다.
물론 처음에는 코드 한번 싸악 다 적으면서 구조 생각 해보고
그 다음에 복습 겸 다시 보면서 왜 이렇게 만들었는지 분석 하는 과정으로 공부하면 좋을 것 같다.
처음부터 계획하고 만드는 완성작품과는 다르게
모든 것이 처음이고 왜 이렇게 되는지 스스로 알아가는 과정이 공부라고 생각 하게 되었다.
그리고 취업을 한다면 다른사람과 협업 하는 과정이 생기고 다른 사람들이 만들어 놓은 코드에서 추가하거나 수정 하는 과정을 주로 할거라 예상하는데 따라하는 과정에서 내가 이해를 제대로 못한 것 같다는 걸 느낀 이상 난 매우 위험한게 아닐까 생각이 되었다.
그런데 왜 다시 공부하게 되었냐고 물어본다면 나의 대답은 간단하다
"따라했다가 뭔가 빠트렸는지 실행이 이상하고 문제를 찾으려하니 너무 오래걸리고 어질 어질 해서 빠르게 다시 만들겠다"
'TIL' 카테고리의 다른 글
2024- 02 - 12프로그래머스 연습 문제 대충 만든 자판 (0) | 2025.02.12 |
---|---|
2025- 02 - 10 기록 ( 언리얼 UFUNCTION 오류) (0) | 2025.02.10 |
2025 - 02 - 06 기록 (0) | 2025.02.06 |
2025- 02- 05 공부 벡터에서 정규화를 사용하는 이유 (0) | 2025.02.05 |
2025 02 04 - 공부내용 (언리얼 충돌 감지) (0) | 2025.02.04 |