programmers.co.kr/learn/courses/30/lessons/42587

 

코딩테스트 연습 - 프린터

일반적인 프린터는 인쇄 요청이 들어온 순서대로 인쇄합니다. 그렇기 때문에 중요한 문서가 나중에 인쇄될 수 있습니다. 이런 문제를 보완하기 위해 중요도가 높은 문서를 먼저 인쇄하는 프린��

programmers.co.kr

 

 

※ 절대적인 해답은 당연히 아니고 제 마음대로 풀었으니 참고용으로 봐주세요

 

 

어떻게 풀까 고민을 하다 location값을 언제 찾아줘야 하는지가 애매해서 queue에 index값을 넣어주기로 했다.

 

1. q를 만들고 거기에 priorities(vector<int>) 우선순위들이 들어있는 벡터의 사이즈만큼 값을 채워준다. 

 

	for (int i = 0; i < p_size; ++i)
	{
		q.push(i);
	}

 

2. while문을 돌면서 queue의 값을 체크

2-1. q의 제일 앞에 있는 index값을 빼온다 

(여기의 index값이란 priorities 벡터의 index를 가리키는 값임)

2-2. for문을 돌면서 현재의 index값(temp)과 i의 값을 비교해 나보다 더 큰 우선순위가 존재한다면 해당 인덱스 값이 맨 뒤로 가게 큐에서 빼서 다시 넣어준다. 

2-3. 만약에 인덱스 값의 변화가 일어나지 않았다면(=내가 제일 우선순위가 크다면) for문 안에서 IsChange가 true가 되지 않았을 것이므로 false이면 큐에서 인덱스를 빼주고 해당 인덱스값이 가리키는 우선순위 벡터의 값을 0으로 만들어준다. 

왜 0인지? 우선순위는 1~9로 0이면 어떠한 우선순위보다 작게 되므로 for문 안에서 체크 시 제외된다.

2-4. 만약 IsChange가 false일 때 temp값(현재 검사하고 있는 index값)이 location과 같다면 while문을 나와서 결과값을 리턴한다. 

 

int solution(vector<int> priorities, int location) {
	int answer = 0;
	int p_size = priorities.size();
	queue<int> q;

	for (int i = 0; i < p_size; ++i)
	{
		q.push(i);
	}

	while (1)
	{
		int temp = q.front();

		int IsChange = false;
		for (int i = 0; i < p_size; ++i)
		{
			if (i == temp)
			{
				continue;
			}
			if (priorities[temp] < priorities[i])
			{
				q.pop();
				q.push(temp);
				IsChange = true;
				break;
			}
		}

		if (!IsChange)
		{
			
			q.pop();
			priorities[temp] = 0;
			answer += 1;
			if (temp == location)
			{
				break;
			}

		}
	}

	return answer;
}

 

 

programmers.co.kr/learn/courses/30/lessons/60057?language=cpp

 

코딩테스트 연습 - 문자열 압축

데이터 처리 전문가가 되고 싶은 어피치는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문자

programmers.co.kr

 

 

 

int solution(string s) {
	int answer = 1001;// s의 길이가 최대 1000이므로
	int s_size = s.length();

	string temp = "";
	int same = 1;

	if (s_size == 1)
	{
		return 1;
	}

	for (int i = 1; i<= s_size / 2; ++i)
	{
		string save = "";
		for (int j = 0; j < s_size; j+=i) {

			temp = s.substr(j, i);

			if (temp.length() % i != 0)
			{
				if (same != 1) {
					save += to_string(same);
				}
				save += temp;
				break;
			}
			string value = s.substr(i + j, i);
			if (temp == value)
			{
				// 같으면
				same += 1;
			}
			else
			{
				// 다르면
				if (same != 1) {
					save += to_string(same);
				}
				save += temp;
				same = 1;
			}
		}

		int temp_length = save.length();

		if (temp_length < answer)
		{
			answer = temp_length;
		}
		
	}

	return answer;
}

 

이.. 이게 생각보다 어려웠다. 이거 레벨2 맞나?

왜.. 왜이렇게 어렵지... 너무 어렵게 생각했나? 계속 고치고 고치다가 맞았는데 앞에 풀었던건 왜 틀렸는지 모르겠음

programmers.co.kr/learn/courses/30/lessons/67258

 

코딩테스트 연습 - 보석 쇼핑

["DIA", "RUBY", "RUBY", "DIA", "DIA", "EMERALD", "SAPPHIRE", "DIA"] [3, 7]

programmers.co.kr

 

 

카카오 블로그의 해설과 질문하기 란을 보니 투포인터 방식으로 해결하라고 했다.

질문하기에서 어떤 분이 링크해주신 블로그 주소인데 깔끔하게 정리가 잘 돼 있어서 한번에 이해했다.

blog.naver.com/kks227/220795165570

 

 

vector<int> solution(vector<string> gems) {
	vector<int> answer;
	int gems_size = gems.size();
	int min_dist = 100001;

	unordered_map<string, int> list;

	unordered_set<string> s_temp;
	for (int i = 0; i < gems_size; ++i)
	{
		s_temp.insert(gems[i]);
	}
	int kind = s_temp.size();

	int idx_r = 0, idx_l = 0;


	while (1)
	{
		if (list.size() >= kind)
		{
			// 해당 key에 있는 value값을 하나 줄여준다.
			list[gems[idx_l]]--;

			if (list[gems[idx_l]] == 0)
			{
				// l의 포인터를 증가시킬 것이므로 지워준다.
				list.erase(gems[idx_l]);
			}
			// 포인터 증가
			idx_l++;
		}
		else if (idx_r == gems_size)
		{
			break;
		}
		else
		{
			list[gems[idx_r]]++;
			idx_r++;
		}

		if (list.size() == kind)
		{
			int temp = idx_r - idx_l;
			if (temp < min_dist)
			{
				answer.clear();
				answer.push_back(idx_l + 1);
				answer.push_back(idx_r);
				min_dist = temp;
			}
		}
	}

	return answer;
}

 

 

그리고 다시 풀면서 한 번 헤맸던 부분이 있는데 min_dist의 초기값을 설정할 때 gems의 size보다 큰 값을 줘야 한다. 그러니까 

gems의 size를 구해서 +1한 값을 주던지 아니면 gems는 최대 100000개가 들어올 수 있다고 했으니 그것보다 +1한 값을 설정해주거나. 그러지 않으면 r의 포인터값과 gem의 size를 비교해서 break를 하는 부분에서 마지막 부분에 break를 해버려 answer에 idx를 넣지 않는 경우가 발생한다. 구현방법은 여러가지이니까 다른 방식으로 구현했으면 상관없을 수도

 

 

 

바보 같은 그 전의 기록

더보기

이렇게 생각했던 이유는 vector나 list같은 컨테이너를 생각하며 데이터를 넣지 않으면 안들어가지 않나? 그럼 안에 데이터는 언제 채워넣어?ㅠ 내가 넣어주자ㅠ 

라는 생각을 가지고 문제를 풀려고 했어서였다.

처음 문제 읽을 때 answer에 꽂혀서 분명 vector<int>형 반환임에도 string으로 들어온다고 [1, 1] 로 반환해야 되나? 하면서 10분을 고민했던 것과 같은 맥락이다. 

진짜 여태 많은 오류를 만났지만 오늘같은 이런 신박한 뇌의 오류는 또 처음이다.

 

(미해결)이라고 포스팅한지 30분만에 뇌의 오류를 정정했다. 앞으로도 자주 써먹어야겠다. 

 

 

vector<int> solution(vector<string> gems) {
	vector<int> answer;
	int gems_size = gems.size();
	int min_dist = gems_size;

// 중복없는 unordered로 
	unordered_map<string, int> list;
	unordered_set<string> s_temp;  
	for (int i = 0; i < gems_size; ++i)
	{
		s_temp.insert(gems[i]);
	}
	int kind = s_temp.size();

	auto iter = list.begin();

	int idx_r = 0, idx_l = 0;

	if (kind == 1)
	{
		answer.push_back(1);
		answer.push_back(1);
		return answer;
	}

	while (idx_r < gems_size && idx_l < gems_size)
	{
		iter = list.find(gems[idx_r]);
		if (iter != list.end())
		{
			iter->second += 1;
		}
		else
		{
			list.insert(pair<string, int>(gems[idx_r], 1));
		}

		if (list.size() < kind)
		{
			idx_r += 1;
		}
		else if (list.size() >= kind)
		{
			int temp = idx_r - idx_l;
			if (temp < min_dist)
			{
				answer.clear();
				answer.push_back(idx_l + 1);
				answer.push_back(idx_r + 1);
				min_dist = temp;
			}
			iter = list.find(gems[idx_l]);
			iter->second -= 1;
			if (iter->second == 0)
			{
				list.erase(iter);
			}
			idx_l += 1;
		}
	}
	return answer;
}

이걸 어떻게 고쳐야 할까

문제 1. 보석의 종류를 어떻게 체크해야 될 지 감이 안와서 우선 set으로 (중복x) 넣어두고 size를 받아왔음.

근데 더 좋은 방법은 없나? 

문제 2. 효율성 + 정확성 테스트 57.3 / 100. 어디가 문제인지 모르겠음

 

 

뭐가 문제일까 일단 올려두면 풀다 잊은 다른 문제들처럼 안 까먹을 것 같아서 올려둠. 

혹시 지나가다가 이 난장판인 코드의 문제점을 아시는 분은 저에게 도움을 주세요 

 

 

tech.kakao.com/2020/07/01/2020-internship-test/

 

2020 카카오 인턴십 for Tech developers 문제해설

2020년 카카오의 여름 인턴십이 시작 되었습니다.여름 인턴십의 첫번째 관문인 코딩 테스트가 2020년 5월 9일 오후 2시부터 6시까지 진행되었는데요, 온라인으로 진행되었기 때문에 코로나19로부터

tech.kakao.com

카카오 블로그에 공식 해설이 있습니다!

 

programmers.co.kr/learn/courses/30/lessons/64061

 

코딩테스트 연습 - 크레인 인형뽑기 게임

[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4

programmers.co.kr

 

 

 

stack을 사용해서 푸는 문제이다.

 

우선 인형뽑기 기계의 움직임. moves로 들어오는 정보들은 열을 기준으로 움직인다.

 

0 0 0 0 0
0 0 1 0 3
0 2 5 0 1
4 2 4 4 2
3 5 1 3 1

 

{0,0,0,0,0}, {0,0,1,0,3},{0,2,5,0,1 },{4,2,4,4,2},{3,5,1,3,1}

입력되는 값은 0번째 행, 1번째 행, 2번째 행, 3번째 행... 순으로 가로로 채워지게 된다.

 

그러므로 moves의 값이 1이라면 0번째의 열에 있는 0,0,0,4,3의 값 중 가장 위에 있는 4를 뽑아야 하며

moves의 값이 5라면 4번째 열에 있는 0,3,1,2,1의 값 중 3을 뽑아야 한다.

 

그렇게 뽑은 값은 stack을 이용한 basket에 넣어준다. 

basket에 정보를 넣어줄 때마다 바로 위에 있는 인형의 종류와 비교해 주었다.

문제의 조건은 터트린 인형의 '개수'를 구하는 것이므로 한 번 터트릴 때마다 두 개 씩 더해준다. 

인형의 종류가 같지 않다면 basket에 넣어준다. 

 

 

 

int solution(vector<vector<int>> board, vector<int> moves) {
	int answer = 0;

	stack<int> basket; 
	int cnt = moves.size();
	int board_width = board[0].size();

	for (int i = 0; i < cnt; ++i)
	{
		for (int j = 0; j < board_width; ++j)
		{
			if (board[j][moves[i] - 1] != 0)
			{
				int value = board[j][moves[i] - 1];

				if (!basket.empty() && basket.top() == value )
				{
					answer += 2;
					basket.pop();
				}

				else {
					basket.push(value);

				}

				board[j][moves[i] - 1] = 0;
				break;
			}
		}
	}
	return answer;
}

 

 

 

tech.kakao.com/2020/04/01/2019-internship-test/

 

 

2019 카카오 개발자 겨울 인턴십 코딩 테스트 문제 해설

"2019년 카카오 개발자 겨울 인턴십" 공개 채용을 위한 1차 코딩 테스트가 지난 2019년 11월 9일 오후 2시부터 6시까지 총 4시간에 걸쳐 진행되었습니다. '19년 신입공채 1차 코딩 테스트 시에 7문제가

tech.kakao.com

문제 공식 해설! 

 

더보기

처음에 그냥 stack을 굳이 안써도 되겠지 하는 생각에 basket을 vector로 해서 풀었다. end() - 2의 방식으로 pop_back을 해줬더니 실행은 제대로 됐는데 제출을 하니 27점을 맞아 정신차리고 다시 stack으로 바꿔서 풀었다. 확실히 stack으로 푸니 코드 줄도 줄어들고 더 편하고, 정답이었다. 앞으로는 조건대로 제대로 풀어야겠다.. 

제일 많은 사람들이 푼 문제라 풀어봤는데 다음 문제 풀기가 두렵다 ^-^..

 

https://programmers.co.kr/learn/courses/30/lessons/42626

 

코딩테스트 연습 - 더 맵게

매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같��

programmers.co.kr

 

처음에는 아무생각없이 vector sort를 이용해서 풀었다.

정확성 테스트는 통과했지만 효율성 테스트에서 빨간색 잔치가 열려서 당황했다가 이 문제가 heap 문제라는 것을 깨닫고 priority_queue를 이용해서 풀었다.

 

priority_queue를 이용하면서 뒤에 compare 조건으로 greater를 이용해 오름차순으로 정렬되게 만들었다.

그렇게 해서 top을 했을 때 작은 숫자가 나오는 것을 이용했다.

 

 

int solution(vector<int> scoville, int K)
{
	int answer = 0;
	int scoville_size = scoville.size();

	priority_queue<int, vector<int>, greater<int>> t_scoville;

	for (int i = 0; i < scoville_size ; ++i)
	{
		t_scoville.push(scoville[i]);
	}

	while (1)
	{
		if (t_scoville.empty())
			return -1;

		if (t_scoville.size() == 1)
		{ 
			// 혹시 처음 조건 자체가 어떻게 될 지 모르니까 추가해 놓은 조건

			//음식이 하나인데 그 음식의 스코빌 지수가 K보다 작으면 -1
			if (t_scoville.top() < K)
				return -1;
		}

		// 가장 안 매운것 (temp_food1)과 그 다음으로 안 매운것(temp_food2)를 뽑아 스코빌 지수를 계산한다.
		auto temp_food1 = t_scoville.top();
		t_scoville.pop();
		auto temp_food2 = t_scoville.top();
		t_scoville.pop();

		int temp_scoville = temp_food1 + (temp_food2 * 2);

		t_scoville.push(temp_scoville);

		answer += 1;

		// 정렬된 상태의 scoville 지수. 만약 top의 값이 K보다 크다면 뒤의 것들은 당연히 더 클 것이므로 break한다.
		if (t_scoville.top() > K)
			break;
	}
	return answer;
}

https://programmers.co.kr/learn/courses/30/lessons/42588

 

코딩테스트 연습 - 탑 | 프로그래머스

수평 직선에 탑 N대를 세웠습니다. 모든 탑의 꼭대기에는 신호를 송/수신하는 장치를 설치했습니다. 발사한 신호는 신호를 보낸 탑보다 높은 탑에서만 수신합니다. 또한, 한 번 수신된 신호는 다른 탑으로 송신되지 않습니다. 예를 들어 높이가 6, 9, 5, 7, 4인 다섯 탑이 왼쪽으로 동시에 레이저 신호를 발사합니다. 그러면, 탑은 다음과 같이 신호를 주고받습니다. 높이가 4인 다섯 번째 탑에서 발사한 신호는 높이가 7인 네 번째 탑이 수신하고, 높이가 7

programmers.co.kr

 

더보기

수평 직선에 탑 N대를 세웠습니다. 모든 탑의 꼭대기에는 신호를 송/수신하는 장치를 설치했습니다. 발사한 신호는 신호를 보낸 탑보다 높은 탑에서만 수신합니다. 또한, 한 번 수신된 신호는 다른 탑으로 송신되지 않습니다.

예를 들어 높이가 6, 9, 5, 7, 4인 다섯 탑이 왼쪽으로 동시에 레이저 신호를 발사합니다. 그러면, 탑은 다음과 같이 신호를 주고받습니다. 높이가 4인 다섯 번째 탑에서 발사한 신호는 높이가 7인 네 번째 탑이 수신하고, 높이가 7인 네 번째 탑의 신호는 높이가 9인 두 번째 탑이, 높이가 5인 세 번째 탑의 신호도 높이가 9인 두 번째 탑이 수신합니다. 높이가 9인 두 번째 탑과 높이가 6인 첫 번째 탑이 보낸 레이저 신호는 어떤 탑에서도 수신할 수 없습니다.

송신 탑(높이)수신 탑(높이)
5(4) 4(7)
4(7) 2(9)
3(5) 2(9)
2(9) -
1(6) -

맨 왼쪽부터 순서대로 탑의 높이를 담은 배열 heights가 매개변수로 주어질 때 각 탑이 쏜 신호를 어느 탑에서 받았는지 기록한 배열을 return 하도록 solution 함수를 작성해주세요.

제한 사항

  • heights는 길이 2 이상 100 이하인 정수 배열입니다.
  • 모든 탑의 높이는 1 이상 100 이하입니다.
  • 신호를 수신하는 탑이 없으면 0으로 표시합니다.

입출력 예


[6,9,5,7,4] [0,0,2,2,4]
[3,9,9,3,5,7,2] [0,0,0,3,3,3,6]
[1,5,3,6,7,6,5] [0,0,2,0,0,5,6]

입출력 예 설명

입출력 예 #1
앞서 설명한 예와 같습니다.

 

입출력 예 #2

[1,2,3] 번째 탑이 쏜 신호는 아무도 수신하지 않습니다.
[4,5,6] 번째 탑이 쏜 신호는 3번째 탑이 수신합니다.
[7] 번째 탑이 쏜 신호는 6번째 탑이 수신합니다.

 

입출력 예 #3

[1,2,4,5] 번째 탑이 쏜 신호는 아무도 수신하지 않습니다.
[3] 번째 탑이 쏜 신호는 2번째 탑이 수신합니다.
[6] 번째 탑이 쏜 신호는 5번째 탑이 수신합니다.
[7] 번째 탑이 쏜 신호는 6번째 탑이 수신합니다.

 

 

 

#include <string>
#include <vector>

using namespace std;

vector<int> solution(vector<int> heights) {
	vector<int> answer(heights.size());

	for (int i = heights.size() - 1; i >= 0; i--) {

		for (int j = i - 1; j >= 0; j--) {
			if (heights[i] < heights[j]) {
				answer[i] = j+1;
				break;
			}
		}
	}
	return answer;
}

 

 

 

https://programmers.co.kr/learn/courses/30/lessons/12980

 

코딩테스트 연습 - 점프와 순간 이동 | 프로그래머스

OO 연구소는 한 번에 K 칸을 앞으로 점프하거나, (현재까지 온 거리) x 2 에 해당하는 위치로 순간이동을 할 수 있는 특수한 기능을 가진 아이언 슈트를 개발하여 판매하고 있습니다. 이 아이언 슈트는 건전지로 작동되는데, 순간이동을 하면 건전지 사용량이 줄지 않지만, 앞으로 K 칸을 점프하면 K 만큼의 건전지 사용량이 듭니다. 그러므로 아이언 슈트를 착용하고 이동할 때는 순간 이동을 하는 것이 더 효율적입니다. 아이언 슈트 구매자는 아이언 슈트를 착용

programmers.co.kr

 

 

 

 

 

더보기

OO 연구소는 한 번에 K 칸을 앞으로 점프하거나, (현재까지 온 거리) x 2 에 해당하는 위치로 순간이동을 할 수 있는 특수한 기능을 가진 아이언 슈트를 개발하여 판매하고 있습니다. 이 아이언 슈트는 건전지로 작동되는데, 순간이동을 하면 건전지 사용량이 줄지 않지만, 앞으로 K 칸을 점프하면 K 만큼의 건전지 사용량이 듭니다. 그러므로 아이언 슈트를 착용하고 이동할 때는 순간 이동을 하는 것이 더 효율적입니다. 아이언 슈트 구매자는 아이언 슈트를 착용하고 거리가 N 만큼 떨어져 있는 장소로 가려고 합니다. 단, 건전지 사용량을 줄이기 위해 점프로 이동하는 것은 최소로 하려고 합니다. 아이언 슈트 구매자가 이동하려는 거리 N이 주어졌을 때, 사용해야 하는 건전지 사용량의 최솟값을 return하는 solution 함수를 만들어 주세요.

예를 들어 거리가 5만큼 떨어져 있는 장소로 가려고 합니다.
아이언 슈트를 입고 거리가 5만큼 떨어져 있는 장소로 갈 수 있는 경우의 수는 여러 가지입니다.

  • 처음 위치 0 에서 5 칸을 앞으로 점프하면 바로 도착하지만, 건전지 사용량이 5 만큼 듭니다.
  • 처음 위치 0 에서 2 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 2) x 2에 해당하는 위치로 이동할 수 있으므로 위치 4로 이동합니다. 이때 1 칸을 앞으로 점프하면 도착하므로 건전지 사용량이 3 만큼 듭니다.
  • 처음 위치 0 에서 1 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 1) x 2에 해당하는 위치로 이동할 수 있으므로 위치 2로 이동됩니다. 이때 다시 순간이동 하면 (현재까지 온 거리 : 2) x 2 만큼 이동할 수 있으므로 위치 4로 이동합니다. 이때 1 칸을 앞으로 점프하면 도착하므로 건전지 사용량이 2 만큼 듭니다.

위의 3가지 경우 거리가 5만큼 떨어져 있는 장소로 가기 위해서 3번째 경우가 건전지 사용량이 가장 적으므로 답은 2가 됩니다.

 

 

 

입출력 예

 

N Result
5 2
6 2
5000 5

입출력 예 설명

입출력 예 #1
위의 예시와 같습니다.

 

입출력 예 #2
처음 위치 0 에서 1 칸을 앞으로 점프한 다음 순간이동 하면 (현재까지 온 거리 : 1) x 2에 해당하는 위치로 이동할 수 있으므로 위치 2로 이동합니다. 이때 1 칸을 앞으로 점프하면 위치3으로 이동합니다. 이때 다시 순간이동 하면 (현재까지 온 거리 : 3) x 2 이동할 수 있으므로 위치 6에 도착합니다. 이 경우가 건전지 사용량이 가장 적으므로 2를 반환해주면 됩니다.

 

입출력 예 #3
위와 같은 방식으로 합니다.

 

 

#include <iostream>
using namespace std;

int solution(int n)
{
	int ans = 0;
	int remain_meter = n;
	for (int i = remain_meter; i > 0; i /= 2) {
		if (i % 2 == 1) {
			ans += 1;
		}
	}
	return ans;
}

 

 

 

+ Recent posts