2025-02-07TIL 알고리즘, 과제, 테이블 생성

별빛에소원을·2025년 2월 7일

TeamSparta-Unreal1기-TIL

목록 보기
39/90

알고리즘 : 프로그래머스 신고결과 받기

내풀이

#include <string>
#include <vector>
#include <unordered_map>
#include <set>
using namespace std;
struct Report
{
	Report() : ReportedCount(0), Stop(false), MailCount(0), ReportLog{} {}
	set<string> ReportLog;
	int ReportedCount;
	int MailCount;
	bool Stop;
};
vector<int> solution(vector<string> id_list, vector<string> report, int k)
{
	// 신고한 유저는 신고당한 유저가 k번 신고당할 경우 메일을 회신받는다.
	unordered_map<string, Report> mapReport;
	for (string str : id_list)
	{
		mapReport[str] = Report();
	}
	for (string& str : report)
	{
		vector<string> split;
		string temp;
		char separator = ' ';
		// Split report
		for (char c : str)
		{
            temp += c;
			if (c == separator)
			{
                temp.pop_back();
				split.push_back(temp);
				temp = "";
			}
		}
		split.push_back(temp);
		// split[0] = ReportUser, split[1] = ReportedUser			
        // 이미 신고를 했다면 처리하지 않는다.
		if(mapReport[split[0]].ReportLog.count(split[1]) == 0)
			mapReport[split[1]].ReportedCount++;        
        mapReport[split[0]].ReportLog.insert(split[1]);
        // k번이상 신고당한 유저면 정지시킨다.
		if (mapReport[split[1]].ReportedCount >= k)
		{
			mapReport[split[1]].Stop = true;
		}
	}
	vector<int> answer;
    // 해당 유저가 신고한 유저들이 정지당했는지 확인 하고, 메일 카운트를 올린다.        
    for(string str : id_list)
    {			
        for(const string& reported : mapReport[str].ReportLog)
        {
            if (mapReport[reported].Stop)
            {
                mapReport[str].MailCount++;
            }            
        }
        answer.push_back(mapReport[str].MailCount);
    }
	return answer;
}

struct를 쓴거 까지는 좋았는데 결과적으로는 깔끔하지 않은거 같다.

베스트 풀이

#include <bits/stdc++.h>
#define fastio cin.tie(0)->sync_with_stdio(0)
using namespace std;

vector<int> solution(vector<string> id_list, vector<string> report, int k) {
    // 1.
    const int n = id_list.size();
    map<string, int> Conv;
    for (int i = 0; i < n; i++) Conv[id_list[i]] = i;

    // 2.
    vector<pair<int, int>> v;
    sort(report.begin(), report.end());
    report.erase(unique(report.begin(), report.end()), report.end());
    for (const auto& s : report) {
        stringstream in(s);
        string a, b; in >> a >> b;
        v.push_back({ Conv[a], Conv[b] });
    }

    // 3.
    vector<int> cnt(n), ret(n);
    for (const auto& [a, b] : v) cnt[b]++;
    for (const auto& [a, b] : v) if (cnt[b] >= k) ret[a]++;
    return ret;
}

자료 관리 시스템

#include <vector>
#include <unordered_map>
#include <set>
#include <string>
#include <sstream>
#include <iostream>
#include <map>
#include <numeric>

// 온라인 학습 관리 시스템 구현
using namespace std;
using uint8 = unsigned __int8;
enum ESubject : uint8
{
	Algorithm,
	Cpp,
	Unreal,
	Blueprint,
	Max
};
struct FSubject
{
	FSubject(const ESubject& _Subject, const uint8& _Score) : Subject(_Subject), Score(_Score) {}
	ESubject Subject;
	uint8 Score;
	bool operator<(const FSubject& f) const
	{
		return Subject < f.Subject;
	}
	friend std::ostream& operator<<(std::ostream& o, const FSubject& subject)
	{
		string str;
		switch (subject.Subject)
		{
		case Algorithm: str = "Algorithm"; break;
		case Cpp: str = "Cpp"; break;
		case Unreal: str = "Unreal"; break;
		case Blueprint: str = "Blueprint"; break;
		}
		o << "과목 : " << str << subject.Score;
	}
};
class Student
{
public:
	Student(const int _ID) : ID(_ID) {}
private:
	int ID;
	std::set<FSubject> m_SetSubject;
public:
	int GetScore(const ESubject& Subject)
	{
		auto Finder = m_SetSubject.find(FSubject(Subject, 0));

		if (Finder == m_SetSubject.end())
			return -1;
		return Finder->Score;
	}
	void SetSubject(const ESubject& Subject, const uint8& _Score)
	{
		if (m_SetSubject.count(FSubject(Subject, 0)) == 0)
		{
			m_SetSubject.insert(FSubject(Subject, _Score));
		}
		else
		{
			auto iter = m_SetSubject.find(FSubject(Subject, 0));
			if (iter != m_SetSubject.end())
			{
				m_SetSubject.erase(iter);
				m_SetSubject.insert(FSubject(Subject, _Score));
			}
		}
	}
	void GetAllSubject(std::vector<FSubject>& vec)
	{
		for (const auto& iter : m_SetSubject)
		{
			vec.push_back(iter);
		}
	}
};
class OnlineStudySystem
{
public:
	OnlineStudySystem() {}
private:
	std::unordered_map<int, std::unique_ptr<Student>> m_mapStudent;
public:
	void InsertGrade(int ID, ESubject Subject, uint8 Score)
	{
		if (m_mapStudent[ID] == nullptr)
		{
			m_mapStudent[ID] = make_unique<Student>(ID);
		}
		m_mapStudent[ID]->SetSubject(Subject, Score);
	}
	void PrintStudentGrade(int ID)
	{
		vector<FSubject> vecSubject;
		m_mapStudent[ID]->GetAllSubject(vecSubject);

		cout << ID << "의 성적" << endl;
		for (FSubject& iter : vecSubject)
		{
			switch (iter.Subject)
			{
			case ESubject::Algorithm: cout << "Algorithm : "; break;
			case ESubject::Blueprint: cout << "Blueprint : "; break;
			case ESubject::Cpp: cout << "C++ : "; break;
			}
			cout << (int)iter.Score << "점" << endl;
		}
	}
	void PrintAllStudentGrade()
	{
		for (const auto& iter : m_mapStudent)
		{
			PrintStudentGrade(iter.first);
		}
	}
	// 과목별 평균점수 , 소수점 둘째자리 까지 표시
	void PrintStudentAvrScore()
	{
		// 전체 점수를 더했을 것.
		map<ESubject, float> mapScore;
		for (int Subject = Algorithm; Subject < Max; ++Subject)
		{
			for (const auto& iter : m_mapStudent)
			{
				int result = iter.second->GetScore((ESubject)Subject);
				if (result != -1)
					mapScore[(ESubject)Subject] += (float)iter.second->GetScore((ESubject)Subject);
			}
		}
		// 전체 학생 수
		size_t size = m_mapStudent.size();
		cout << "과목 평균 " << endl;
		for (int Subject = Algorithm; Subject <= Cpp; ++Subject)
		{
			mapScore[(ESubject)Subject] /= (float)size;
			ostringstream oss;

			switch ((ESubject)Subject)
			{
			case Algorithm: oss << "Algorithm : "; break;
			case Cpp: oss << "Cpp : "; break;
			case Unreal: oss << "Unreal : "; break;
			case Blueprint: oss << "Blueprint : "; break;
			}

			cout << oss.str();
			cout << fixed;
			cout.precision(2);
			cout << mapScore[(ESubject)Subject] << "점" << endl;
		}
	}
	// 과목별 최고점수 학생
	int GetGrateStudent(ESubject Subject)
	{
		auto iter = max_element(m_mapStudent.begin(), m_mapStudent.end(), [Subject](
			const auto& a,
			const auto& b)->bool
			{
				return a.second->GetScore(Subject) < b.second->GetScore(Subject);
			});

		return iter->first;
	}
	void PrintGrateScore()
	{
		cout << "과목별 최고 점수 학생 " << endl;
		for (int Subject = Algorithm; Subject <= Cpp; ++Subject)
		{
			ostringstream oss;

			switch ((ESubject)Subject)
			{
			case Algorithm: oss << "Algorithm : "; break;
			case Cpp: oss << "Cpp : "; break;
			case Unreal: oss << "Unreal : "; break;
			case Blueprint: oss << "Blueprint : "; break;
			}

			oss << GetGrateStudent((ESubject)Subject);
			cout << oss.str() << endl;
		}
	}
	//  성적 구간 검색
	void PrintSearchScore(ESubject Subject, int LowerBound, int UpperBound)
	{
		vector<int> vecStudent;
		switch (Subject)
		{
		case Algorithm: cout << "Algorithm 점수가 "; break;
		case Cpp: cout << "Cpp 점수가 "; break;
		}
		cout << LowerBound << "이상 " << UpperBound << "이하 " << "학생" << endl;
		for (const auto& iter : m_mapStudent) {
			if (iter.second->GetScore(Subject) >= LowerBound &&
				iter.second->GetScore(Subject) <= UpperBound)
			{
				vecStudent.push_back(iter.first);
			}
		}

		for (int id : vecStudent)
		{
			cout << "학생 : " << id << endl;
		}
	}
	//  과목별 성적 통계(특정 과목의 최고, 최저, 평균, 수강인원)
	void PrintSubjectStatistics(ESubject Subject)
	{
		int StudentCount = m_mapStudent.size();
		int MaxScore, MinScore, AvrScore;

		MaxScore = GetMaxScore(Subject);
		MinScore = GetMinScore(Subject);
		AvrScore = GetAvrScore(Subject);

		cout << GetSubjectString(Subject) << "과목의 통계" << endl;
		cout << "최고 점수 : " << MaxScore << endl;
		cout << "최저 점수 : " << MinScore << endl;
		cout << "평균 점수 : " << AvrScore << endl;
		cout << "총 학생 : " << StudentCount << endl;
	}
private:
	uint8 GetMaxScore(ESubject Subject)
	{
		auto iter = max_element(m_mapStudent.begin(), m_mapStudent.end(), [Subject](const auto& a, const auto& b)->bool
			{
				return a.second->GetScore(Subject) < b.second->GetScore(Subject);
			}
		);

		return iter->second->GetScore(Subject);
	}
	uint8 GetMinScore(ESubject Subject)
	{
		auto iter = min_element(m_mapStudent.begin(), m_mapStudent.end(), [Subject](const auto& a, const auto& b)->bool
			{
				return a.second->GetScore(Subject) < b.second->GetScore(Subject);
			}
		);

		return iter->second->GetScore(Subject);
	}
	float GetAvrScore(ESubject Subject)
	{
		vector<uint8> vecScore;
		for (const auto& iter : m_mapStudent)
		{
			vecScore.push_back(iter.second->GetScore(Subject));
		}

		int sum = accumulate(vecScore.begin(), vecScore.end(), 0);

		return sum / vecScore.size();
	}
	string GetSubjectString(ESubject Subject)
	{
		switch (Subject)
		{
		case ESubject::Algorithm: return "Algorithm";
		case ESubject::Blueprint: return "Blueprint";
		case ESubject::Cpp: return "Cpp";
		case ESubject::Unreal: return "Unreal";
		}
	}
};
int main()
{
	OnlineStudySystem System;
	System.InsertGrade(1001, ESubject::Cpp, 85);
	System.InsertGrade(1001, ESubject::Algorithm, 90);
	System.InsertGrade(1002, ESubject::Cpp, 92);
	System.InsertGrade(1002, ESubject::Algorithm, 78);
	System.InsertGrade(1003, ESubject::Cpp, 95);
	System.InsertGrade(1003, ESubject::Algorithm, 95);
	System.InsertGrade(1001, ESubject::Algorithm, 85);
	// 학생성적 조회
	//System.PrintStudentGrade(1001);
	System.PrintAllStudentGrade();
	System.PrintStudentAvrScore();
	System.PrintGrateScore();
	System.PrintSearchScore(Cpp, 90, 95);
	System.PrintSubjectStatistics(Cpp);
	return NULL;
}

꽤 재밌던 과제라고 생각한다. 다만 Set말고 그냥 Map을 썼으면 좀 더 코드도 짧고 구현도 간단하게 됬을거 같다.

max_element

배열에서 최대값을 구하는 함수다 3번째 인자로 배열이 객체일 경우 원하는 값을 설정할 수 있다.

rangs

TSubclassOf

profile
취미로 게임하는사람

0개의 댓글