프로그래머스 - 모의고사(lv1)

문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.

1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.


문제 풀이

소스코드:

#include <string>
#include <vector>
#include <iostream>
#include <functional>


using namespace std;

template <typename T>
class MaxHeap
{
	vector<pair<int, T>> array;

public:
	MaxHeap() {}
	void insert(int x, T item)
	{
		array.push_back(pair<int, T>(x, item));
		int target = array.size();
		while( target > 1 && x > array[(target/2)-1].first) {
			array[target-1].first = array[(target/2)-1].first;
			array[target-1].second = array[(target/2)-1].second;
			//cout << "target = " << target << ", target/2 = " << target/2 << endl;
			target /= 2;
			//cout << "target:" << target << endl;
		}
		//cout << "======end target========target:" << target << endl;
		array[target-1].first = x;
		array[target-1].second = item;
	}

	pair<int, T> popMax()
	{
		//max is always first factor by heapify(insert)
		pair<int, T> maxpair(array.front().first,array.front().second);

		//end factor moves to first factor
		array.front().first = array.back().first;
		array.front().second = array.back().second;
		array.pop_back();

		//heapify
		int x = array.front().first;
		T xitem = array.front().second;
		int parent=1, child=2;
		int arrSize = array.size();
		while(child <= arrSize) {
			if(array[child-1].first < array[child].first) {
				child++;
			}
			if(x >= array[child-1].first) {
				break;
			}
			array[parent-1].first = array[child-1].first;
			array[parent-1].second = array[child-1].second;
			parent=child;
			child *= 2;
		}
		array[parent-1].first = x;
		array[parent-1].second = xitem;

		return maxpair;
	}

	pair<int, T> getMax()
	{
		//max is always first factor by heapify(insert)
		return array.front();
	}


	bool isEmpty()
	{
		if(array.empty())
			return true;
		return false;
	}

	int factorSize()
	{
		return array.size();
	}

	void print()
	{
		cout << endl << "=============print=============" << endl;
		typename vector<pair<int, T> >::iterator iter;
		for(iter = array.begin(); iter != array.end(); iter++){
			cout<<iter->first << "(" << iter->second << ")" << " ";
		}
		cout << endl << "===============================" << endl;
	}

	void printtree(int index, int space)
	{
		if(array.size() < index) {
			return;
		}

		space += 4;
		printtree((index*2)+1, space); //right
		for(int i=4;i<space;i++) {
			cout << " ";
		}

		cout << array[index-1].first << "(" << array[index-1].second << ")"<< endl;
		printtree((index*2), space); //left
	}

	void printtree()
	{
		printtree(1, 0);
	}

};

template <typename T>
class MinHeap
{
private :
	vector<T> array;

	// c style
	//bool (*compare)(...);
	function<bool(T first, T second)> compare;

	static bool dcompare(T first, T second)
	{
		return first > second;
	}


public:
	MinHeap()
	{
		compare = this->dcompare;
	}
	MinHeap(function<bool(T first, T second)> usercompare)
	{
		compare = usercompare;
	}

	void insert(T x)
	{
		array.push_back(x);
		int target = array.size();
		while( target > 1 && !compare(x,array[(target/2)-1]) ) {
			array[target-1] = array[(target/2)-1];
			//cout << "target = " << target << ", target/2 = " << target/2 << endl;
			target /= 2;
			//cout << "target:" << target << endl;
		}
		//cout << "======end target========target:" << target << endl;
		array[target-1] = x;
	}

	T popMin()
	{
		//min is always first factor by heapify(insert)
		T min = array.front();

		//end factor moves to first factor
		array.front() = array.back();
		array.pop_back();

		//heapify
		T x = array.front();
		int parent=1, child=2;
		int arrSize = array.size();
		while(child <= arrSize) {
			if( compare(array[child-1], array[child]) ) {
				child++;
			}
			if( !compare(x,array[child-1]) || (x == array[child-1]) ) {
				break;
			}
			array[parent-1] = array[child-1];
			parent=child;
			child *= 2;
		}
		array[parent-1] = x;

		return min;
	}

	T getMin()
	{
		//min is always first factor by heapify(insert)
		return array.front();
	}


	bool isEmpty()
	{
		if(array.empty())
			return true;
		return false;
	}

	int factorSize()
	{
		return array.size();
	}

	void print()
	{
		cout << endl << "=============print=============" << endl;
		for (vector<int>::const_iterator item=array.begin(); item != array.end();++item) {
			cout<<*item << " ";
		}
		cout << endl << "===============================" << endl;
	}

	void printtree(int index, int space)
	{
		if(array.size() < index) {
			return;
		}

		space += 4;
		printtree((index*2)+1, space); //right
		for(int i=4;i<space;i++) {
			cout << " ";
		}

		cout << array[index-1] << endl;
		printtree((index*2), space); //left
	}

	void printtree()
	{
		printtree(1, 0);
	}
};



vector<int> solution(vector<int> answers) {
    vector<int> answer;

	vector<vector<int>> person{
		{1,2,3,4,5},
		{2,1,2,3,2,4,2,5},
		{3,3,1,1,2,2,4,4,5,5},
	};

	int sum[3]={0,};
	MaxHeap<int> maxheap;

	for(int i=0; i<person.size(); i++) {
		for(int j=0; j<answers.size(); j++) {
			//cout << person[i][j%person[i].size()] << endl;
			int num = j%person[i].size();
			if(person[i][num] == answers[j])
				sum[i]++;
		}
		//cout << "sum ! " << sum[i] << endl;
		maxheap.insert(sum[i],i+1);
	}

	//maxheap.printtree();
	while(!maxheap.isEmpty()) {
		pair<int,int> maxpair = maxheap.popMax();
		answer.push_back(maxpair.second);
		pair<int,int> next = maxheap.getMax();
		if(maxpair.first != next.first){
			break;
		}
	}

	//sort
	MinHeap<int> rank;
	while(answer.size() > 0) {
		rank.insert(answer.back());
		answer.pop_back();
	}

	//rank.printtree();
	while(!rank.isEmpty()) {
		int min = rank.popMin();
		answer.push_back(min);
	}


	return answer;
}

/*
int main()
{
	vector<int> myanswers{
		1,3,2,4,2
	};


	vector<int> ret = solution(myanswers);
	cout << "ret {";
	for(typename vector<int>::iterator itr = ret.begin(); itr != ret.end();++itr)
	{
		cout << *itr << ", ";
	}
	cout << "}" << endl;

	cout << endl;
}
*/




해설

단순 3명의 비교이지만 범용성을 위해 person이라는 2차원 vector를 만들었습니다.
	vector<vector<int>> person{
		{1,2,3,4,5},
		{2,1,2,3,2,4,2,5},
		{3,3,1,1,2,2,4,4,5,5},
	};

각 person별로 문제의 갯수만큼 나의 답안 list를 비교합니다.
그리고 정답 갯수는 최대순서대로 max heap으로 sorting합니다.
이 때 정답 갯수와 어떤 사람인지에 대한 정보가 같이 가야하기 때문에 2차원 heap으로 sorting합니다.
	for(int i=0; i<person.size(); i++) {
		for(int j=0; j<answers.size(); j++) {
			//cout << person[i][j%person[i].size()] << endl;
			int num = j%person[i].size();
			if(person[i][num] == answers[j])
				sum[i]++;
		}
		//cout << "sum ! " << sum[i] << endl;
		maxheap.insert(sum[i],i+1);
	}


이렇게 정렬된 정답의 갯수를 다시 사람 순으로 정렬합니다.
	//sort
	MinHeap<int> rank;
	while(answer.size() > 0) {
		rank.insert(answer.back());
		answer.pop_back();
	}

	//rank.printtree();
	while(!rank.isEmpty()) {
		int min = rank.popMin();
		answer.push_back(min);
	}

결과




댓글