https://www.acmicpc.net/problem/2609

 

문제 해결 일자 : 2024.10.08(화)

난이도 : 브론즈 1(Solved.ac)

문제 풀이 /  코드 구현 :  알고리즘 참고를 위해 검색(구글링) / 직접

더보기

카테고리 : 수학 , 정수론 , 유클리드 호제법


문제 내용 : 입력으로 두 정수가 들어올때, 두 수의 최대 공약수와 최소 공배수를 출력하면된다.

 

문제 풀이 : 

최대 공약수를 구하기 위해서 소인수분해를 하게 되면 시간복잡도에 걸리게 된다

 

유클리드 호제법 이라는것을 사용하면 시간복잡도만 잡을뿐만 아니라 최소공배수도 같이 계산이된다.

나무위키 출처

이렇게 문장으로 보게되면 무슨말인가 부터 의문이 들지만, 이해하면 정말 간단한 말이다.

진짜 중요한 문장이 문장이다.

우리는 반복문으로 나머지가 0일때까지 루프를 돌리다

r=0이 되는 구간이 나오면 b를 최대공약수로 선택하면된다.

 

유클리드 호제법 활용 예시)

 

최소공배수는 (a*b) / gcb(a,b)를 하면 나온다.

 

접근 순서 :

1) 큰수가 작은수를 나눌수 있게 두 정수(a,b)의 대소비교를 한다.

2) 두 정수(a,b)의 /(몫) , %(나머지) 연산 계산을 한다.

3-1) 나머지가 0이 아닌 경우 a,b를 초기화 한다.

a = 두 숫자중 작은숫자(b)

b = 두숫자의 나머지(r)

3-2) 나머자기 0인경우 해당 b를 최대공약수로 선언한뒤 반복문을 탈출한다.

4) 1)과정으로 돌아가 반복한다. 반복문을 탈출한 경우이면 최소공배수 계산을 한다.

 

구현코드 :

더보기
#include <iostream>
#include <string>

using namespace std;


void Swap(int& num1, int& num2)
{
	int tmp = num1;
	num1 = num2;
	num2 = tmp;
}

int main(void)
{
	int num1, num2;

	cin >> num1 >> num2;

    int oldnum1 = num1;
    int oldnum2 = num2;
       
    int result = 0;
    int remainder = 1; 
    int gcb = 0;
    while(remainder != 0)
        {
            if(num1 <num2)
            {
                Swap(num1,num2);
            }
            result = num1 / num2;
            remainder = num1 % num2;

            if(remainder == 0)
            {
                gcb = num2;
                break;
            }
            
            num1 = num2;
            num2 = remainder;
        }
    
    cout << gcb <<endl;

        cout << (oldnum1 * oldnum2) / num2;
	return 0;
}

https://leetcode.com/problems/longest-increasing-subsequence/description/

문제 해결 일자 : 2024.09.25

난이도 : medium

문제 풀이 / 코드 구현 :  검색 참조 / 직접 구현

더보기

카테고리 : 배열 , 이진검색 , 동적프로그래밍(DP)

알고리즘 : LIS(증가하는 수열 알고리즘)


문제 내용 : 

정수 배열이 주어지는데 해당 배열에서 몇개의 정수를 지웠을때 오름차순 정렬이 되는 배열의 최대 갯수를 구하는 문제

 

문제풀이 :

오름차순 정렬이기에 배열을 순회를 돌려서 다음 숫자의 원소값이 크면 자신의 배열에 추가, 낮으면 다음 숫자를 체크하는 식으로 접근한다.

 

하지만 반복문이 돌다 보면 해당 숫자를 지우고 안지우고 유무로 배열의 가짓수가 너무 많아진다.

이 문제는 최대 갯수를 구하는 배열을 반환하는 것이 아닌 배열의 최대 갯수를 구하는것이다.

 

dp로 해당 원소일때 각 원소와의 크기를 비교하여 숫자가 크면 dp값을 증가, 작으면 다음 원소를 확인하여

진행하면된다. 

 

dp는 간단히 말하면 메모하며 풀어가기이다. 순회를 돌때마다 과거의 data를 계속 저장하고

현재의 data에 적용하는 방식이다.

dp 배열의 index는 주어진 배열의 원소 인덱스를 의미하며

dp 배열의 value는 해당 원소로 정렬 될때의 원소의 최대크기를 나타낸다.

 

접근순서 :

1. 원소에서 비교를 할때 필요한 dp 배열 하나를 선언한다.

2. dp배열의 모든 원소를 1로 초기화 해준다. (자기 자신만 있어도 배열의 크기는 1이기 때문에)

3. 숫자 비교를 하여  해당 원소가 클때마다 dp[해당 원소 인덱스]를 증가 시킨다.

3-1. 증가 시킬때 dp[i](해당 원소 인덱스)가 클지 dp[j]+1(전 원소 인덱스)이 대소 비교를하여 큰 value값을 dp[i]에 저장시키면된다. ( dp[j]+1의 +1은 과거 -> 현재로 오면서 최대 크기가 증가하였기에)

4.주어진 정수 배열을 순회 한뒤 제일 큰 value값을 반환하면된다.

 

코드구현 :

더보기
class Solution {
public:
    int lengthOfLIS(vector<int>& nums) 
    {
        int* dp = new int[nums.size()];

        int resultMax = 1;

        for(int i = 0; i < nums.size();i++) dp[i] = 1;

        for(int i = 0; i < nums.size();i++)
        {
            for(int j =0 ; j < i; j++)
            {
                if(nums[i] > nums[j])
                {
                    dp[i] = max(dp[i],dp[j]+1);
                }

                if(dp[i] > resultMax)
                {
                    resultMax = dp[i];
                }

            }
        }

        delete[] dp;

        return resultMax;
    }
};

 

'코딩테스트 > LeetCode' 카테고리의 다른 글

LeetCode :: 733. Flood Fill (C++)  (0) 2024.09.25

https://leetcode.com/problems/flood-fill/description/

문제 해결 일자 : 2024.09.24

난이도 : easy

문제 풀이 /  코드 구현 :  직접 구현 / 직접 구현

더보기

카테고리 : 배열, DFS , BFS , Matrix


문제 내용 : 

좌표(sr,sc)한곳을 시작하여 인접하고 있는 좌표들의 value값을 바꾸는 문제이다.

이때 인접은 상,하,좌,우만 해당된다.


문제 풀이 : 

시작 좌표가 주어지고 자기 자신과 다른 value값을 가졌으면 이동하지 않으면 되고 방향(상,하,좌,우)가 정해졌기에 재귀함수로 접근하여 문제를 풀었다.

 

접근 순서:

1.시작 좌표의 value값을 변경(1 -> 2)한다.

2.방향 순서로 한칸 이동한다.

3.범위를 벗어났거나 처음Value값(1)이 다르면 돌아온다 같은경우 해당 방향으로 한칸 더 이동한다.

4. 2 - 3을 방향값을 변경하며 다 변경 될때까지 반복한다.

 

구현코드

더보기
#include <iostream>
#include <vector>

using namespace std;

class Solution
{
public:

    enum dir { UP = 1, DOWN = -1, LEFT = -1, RIGHT = 1 };

    void FindPixel(vector<vector<int>>& image, int sr, int sc, int pos,int color)
    {
        if((sr < 0 || sr >= image.size()) || (sc < 0 || sc >= image[0].size()))
        {
            return;
        }

        if (image[sr][sc] != pos)
        {
            return;
        }

        image[sr][sc] = color;

        FindPixel(image, sr + UP, sc, pos, color);
        FindPixel(image, sr + DOWN, sc, pos, color);
        FindPixel(image, sr, sc + LEFT, pos, color);
        FindPixel(image, sr, sc + RIGHT, pos, color);
    }

    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc,int color)
    {
        if (image[sr][sc] == color)
       {
           return image;
       }

        FindPixel(image, sr, sc, image[sr][sc], color);

        return image;
    }
};

 

 

'코딩테스트 > LeetCode' 카테고리의 다른 글

LeetCode :: 300. Longest Increasing Subsequence (C++)  (0) 2024.09.25

https://school.programmers.co.kr/learn/courses/30/lessons/42627#

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

  • 문제 설명

    하드디스크는 한 번에 하나의 작업만 수행할 수 있습니다. 디스크 컨트롤러를 구현하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 요청이 들어온 순서대로 처리하는 것입니다.

    예를들어

    - 0ms 시점에 3ms가 소요되는 A작업 요청
    - 1ms 시점에 9ms가 소요되는 B작업 요청
    - 2ms 시점에 6ms가 소요되는 C작업 요청
    

    와 같은 요청이 들어왔습니다. 이를 그림으로 표현하면 아래와 같습니다.

    한 번에 하나의 요청만을 수행할 수 있기 때문에 각각의 작업을 요청받은 순서대로 처리하면 다음과 같이 처리 됩니다.

    - A: 3ms 시점에 작업 완료 (요청에서 종료까지 : 3ms)
    - B: 1ms부터 대기하다가, 3ms 시점에 작업을 시작해서 12ms 시점에 작업 완료(요청에서 종료까지 : 11ms)
    - C: 2ms부터 대기하다가, 12ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 16ms)
    

    이 때 각 작업의 요청부터 종료까지 걸린 시간의 평균은 10ms(= (3 + 11 + 16) / 3)가 됩니다.

    하지만 A → C → B 순서대로 처리하면

    - A: 3ms 시점에 작업 완료(요청에서 종료까지 : 3ms)
    - C: 2ms부터 대기하다가, 3ms 시점에 작업을 시작해서 9ms 시점에 작업 완료(요청에서 종료까지 : 7ms)
    - B: 1ms부터 대기하다가, 9ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 17ms)
    

    이렇게 A → C → B의 순서로 처리하면 각 작업의 요청부터 종료까지 걸린 시간의 평균은 9ms(= (3 + 7 + 17) / 3)가 됩니다.

    각 작업에 대해 [작업이 요청되는 시점, 작업의 소요시간]을 담은 2차원 배열 jobs가 매개변수로 주어질 때, 작업의 요청부터 종료까지 걸린 시간의 평균을 가장 줄이는 방법으로 처리하면 평균이 얼마가 되는지 return 하도록 solution 함수를 작성해주세요. (단, 소수점 이하의 수는 버립니다)

    제한 사항
    • jobs의 길이는 1 이상 500 이하입니다.
    • jobs의 각 행은 하나의 작업에 대한 [작업이 요청되는 시점, 작업의 소요시간] 입니다.
    • 각 작업에 대해 작업이 요청되는 시간은 0 이상 1,000 이하입니다.
    • 각 작업에 대해 작업의 소요시간은 1 이상 1,000 이하입니다.
    • 하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다.
    입출력 예jobsreturn
    [[0, 3], [1, 9], [2, 6]] 9
    입출력 예 설명

    문제에 주어진 예와 같습니다.

    • 0ms 시점에 3ms 걸리는 작업 요청이 들어옵니다.
    • 1ms 시점에 9ms 걸리는 작업 요청이 들어옵니다.
    • 2ms 시점에 6ms 걸리는 작업 요청이 들어옵니다.

 

더보기

문제 풀이 :

 

모든 작업의 요청 시점 시간 에서부터 작업이 완료되는 시간들의 평균값을 구하는 문제다.

문제는 Heap(힙) 카테고리에 있지만 우선순위 큐를 사용하지 않아도 풀리는 문제다.

 

첫번째 중요한점 : 평균은 최소의 원소끼리 합했을때 최소의 평균값이 나온다.

즉, 인자값으로 준 vector를 [작업의 소요시간]을 기준으로 오름차순 정렬을 해서 각 평균을 구하면 된다.

 

두번째 중요한 점 : [ 하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다 ]

이 문장을 잘 봐야된다.  작업이 완료된 시점의 시간에 작업이 없으면 남은 작업 중 요청 시점이 제일 빠른것 부터 다시 평균을 구해주면된다. 

 

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

bool compare(vector<int> a , vector<int> b)
{
     return a[1] < b[1];  
}

int solution(vector<vector<int>> jobs) 
{
    int answer = 0;
    int cur_time =0;
    bool check = false;
    
    vector<vector<int>> results = jobs;

    while(!results.empty())
    {
        check = false;
        sort(results.begin(),results.end(),compare);
        for(int i = 0; i < results.size(); i++)
        {
            if(cur_time >= results[i][0])
            {
                check  = true;
                answer += (cur_time - results[i][0]) + results[i][1];
                cout << cur_time << " "<< results[i][0]<< " "<<results[i][1]<<endl;
                cur_time += results[i][1];
                results.erase(results.begin() + i);
                break;
            }
        }

        if(!check)
        {
            vector<vector<int>> tmp = results;
            sort(tmp.begin(),tmp.end());
            cur_time = tmp[0][0];
            answer += tmp[0][1];
            cout << cur_time << " "<< tmp[0][0]<< " "<<tmp[0][1]<<endl;
            cur_time += tmp[0][1];
            tmp.erase(tmp.begin());
            results = tmp;
        }
    }
    
  cout <<answer;
    
    return answer / jobs.size();
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

LV2.가장 큰 수  (0) 2023.11.03
LV1.둘만의 암호  (0) 2023.10.26
LV1.체육복  (0) 2023.10.26
LV2.택배상자  (0) 2023.10.26
LV2.롤케이크 자르기  (0) 2023.10.26

https://school.programmers.co.kr/learn/courses/30/lessons/42746

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 내용 :

0 또는 양의 정수가 담긴 배열 하나를 인자값으로 줌

배열 원소를 각 이어 붙였을때 가장 큰 수를 반환하는 문제

 

문제 풀이 :

[숫자들의 조합 경우의 수를 찾음 -> 제일 큰값을 반환]

시간 복잡도로 인하여 바로 오답처리 

 

가장 큰 수를 뽑기 위한 조건 

1.배열의 원소(숫자)값의 제일 첫번째 자리가 커야된다.

-> ex) 6 , 10 -> 첫번째 자리 대소비교 ( 6 > 1 ) , 6이 앞으로

2.첫번째 자리가 똑같은 경우 , 해당 숫자를 앞뒤로 붙였을때 큰값을 앞에 붙여야한다 

-> ex) 3 , 34 -> 첫번째 자리가 똑같음 -> 앞뒤로 숫자를 붙여 대소비교 (334 < 343) , 343이 앞으로

 

이 2조건을 사용하여 숫자를 정렬한뒤 문자를 붙이면 원하는 결과값이 나온다.

 

[코드영역]

더보기
#include <string>
#include <vector>
#include <iostream>
#include <algorithm>

//알고리즘 헤더에 sort 함수에 비교자 변경해서 풀었음
//비교자에서 해당 수자를 문자열로 바꾸고 문자열 제일 앞 숫자가 같으면
//해당 숫자문자열을 합친뒤 크기를 비교하여 true인경우 정렬을 하는식으로

//비교자의 해당 숫자의 문자열 앞이 다른경우 대소비교하여 true인경우 정렬 

using namespace std;

bool compare(int a, int b)
{
     string str_lhs = to_string(a) ;
     string str_rhs = to_string(b) ;
    
    switch(str_lhs.front() == str_rhs.front() )
    {
        case true:
            if(str_lhs+str_rhs > str_rhs + str_lhs) { return true;}
            break;
        case false:
            if(to_string(a).front() > to_string(b).front())  {return true;} 
            break;
    }
  
    return false;
}

string solution(vector<int> numbers) {
    string answer = "";
        
    sort(numbers.begin(),numbers.end(),compare);
   
    //정렬된 배열 제알 앞이 0인경우 숫자 완성이 안됬기에 0문자열 리턴 
    if(numbers.front() == 0 ) { return "0";}
    
    for(int num : numbers) {  answer += to_string(num);}

    return answer;
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

LV3.디스크 컨트롤러  (0) 2024.04.08
LV1.둘만의 암호  (0) 2023.10.26
LV1.체육복  (0) 2023.10.26
LV2.택배상자  (0) 2023.10.26
LV2.롤케이크 자르기  (0) 2023.10.26

https://school.programmers.co.kr/learn/courses/30/lessons/155652

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 내용 :

0.인자값으로 s와 skip 이라는 알파벳 소문자 문자열과 index라는 int 정수값이 주어짐

1.s 문자열에 문자를 index 만큼의 뒤의 문자로 변환해야함

2.변환시에 skip이라는 문자열에 해당 문자가 있을경우 그 문자를 무시하고 한번 더 변환함

2-1.변환시 글자 'z'를 넘어가는경우 'a'부터 다시 시작

이때 변환되는 문자열을 return


풀이 : 

문제에서 소문자 알파벳만 사용하기에 'a'~'z'를 담고있는 알파벳 배열을 만들것,

skip문자열의 문자인 경우 배열에 넣지 않으며 알파벳 배열을 만든다.

 

그후 s문자열의 길이만큼 반복문을 순회하며

해당 단일문자가 알파벳배열의 어디 index에 있는지 찾고 

찾은 문자의 index에 인자값index을 더하여 위치를 찾는다.

만약 더한 index값이 알파벳배열의 수를 넘었을 경우 , 다시 'a'부터 시작하게 초기화 한후 찾는다.

 

그럼 최종으로 찾은 index값을 알파벳 배열에 넣어 answer에 추가시키면 된다.

 

코드영역

 

더보기
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;


string solution(string s, string skip, int index) {
    string answer = "";
    
    
    //sort 정렬 : 시간복잡도 N , 우선순위 큐 : 시간복잡도 : log n
    //이기에 우선순위큐를 이용하여 minheap으로 정렬함
    priority_queue<char,vector<char>,greater<char>> pq_skip;
    for(char ch : skip) {  pq_skip.push(ch);}
    
    
    char pivot = 'a'; //알파벳 배열에 넣을 시작 문자
    vector<char> alpabet;
    while(pivot <= 'z') 
    {
        //해당 알파벳이 skip문자열에 있는경우 알파벳 배열에 넣지 않는다.
        if( pq_skip.top() != pivot) { alpabet.push_back(pivot); }
        else { pq_skip.pop(); }
        pivot++;
    }
        
    //문자열 s 길이만큼 순회하며 문자를 변환한다.
    int result;
    for(int i = 0; s.size() >i;i++)
    {
        //문자열 s의 단일문자가 알파벳배열의 어디에 위치하는지 찾는다.
        int alpabet_index = find(alpabet.begin(),alpabet.end(),s[i]) - alpabet.begin();
        
        //찾은 단일문자위치에 인자값index를 더하여 최종 위치를 찾는다.
        result = alpabet_index + index;
        //만약 알파벳 사이즈를 초과한 경우 , 알파벳 사이즈만큼 뺀다.
        while(result> alpabet.size()-1 )
        {
            result -= alpabet.size();
        }
        
        answer += alpabet[result];
    }
    
    
    return answer;
}

해당 문제를 이렇게 풀었지만 , 다른 사람 풀이를 보니 더욱 가독성 좋고 쉽게 풀이한게 있어 코드를 첨부한다.

 

다른사람 풀이

#include <string>
#include <vector>

using namespace std;

string solution(string s, string skip, int index) {
    string answer = "";

    for(auto v : s)
    {
        int t = 0; //다음 문자로 넘어간 숫자를 카운트하는 변수
        int c = v - 'a'; //문자v에서 'a'를 뺌으로 알파벳의 위치순서를 파악
        while(t < index)
        {
            c++;//다음 알파벳위치(알파벳 변환)
            v = (c % 26) + 'a';//해당 알파벳 위치를 문자열로 변환(v는 char 자료형)
            //c%26은 알파벳이 총 26개 이기 때문에 큰 숫자가 들어와도 알파벳의 한 형태로 변환 가능하기떄문
            
            //skip문자열에 해당 문자(v)가 있는지 체크
            if(skip.find(v) == string::npos)
            {
            	//없으면 카운트를 증가시킴
                t++;
            }
        }
        
        answer += v;
    }
    return answer;
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

LV3.디스크 컨트롤러  (0) 2024.04.08
LV2.가장 큰 수  (0) 2023.11.03
LV1.체육복  (0) 2023.10.26
LV2.택배상자  (0) 2023.10.26
LV2.롤케이크 자르기  (0) 2023.10.26

https://school.programmers.co.kr/learn/courses/30/lessons/42862

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제 내용 :

1.체육복이 없는 학생에게 여벌의 체육복이 있는 학생들이 빌려줄 수 있음

1-1.하지만 빌려줄수 있는 경우는 자기 앞 또는 뒤 학생한테만 체육복을 빌려 줄 수 있음

2.체육복은 가지고 있지만 한벌만 가지고있으면 빌려 줄수 없음

3.체육복을 가지고 있어야만 수업을 들을 수 있음

4.여벌 체육복을 갖고있지만 체육복을 한벌 잃어버릴 수 있음

이때 수업을 들을 수 있는 학생의 최대값을 return


풀이 : map자료구조 

학생을 나타내는 key , 체육복의 갯수 value 데이터가 필요하기에 map 자료구조를 활용

1.체육복이 없는 학생들(lost)

2.여벌체육복이 있는 학생들(reserve)

이 두 무리를 하나의 map으로 정리한다.

이 map에 존재 하지 않는 학생은 수업을 들을 수 있는 학생이고

이 map에 있는 학생들에 대해서만 체크하면 된다.

 

그후 map을 학생수(n)만큼 순회하며 앞,뒤를 체크하며 체육복 수를 조정하면 된다.

 

코드 영역

더보기
#include <string>
#include <iostream>
#include <vector>
#include <map>

using namespace std;

//체육복 빌려주는 조건 : 자기 앞,뒷 1번호 만큼 가능
//체육수업을 들을수있는 학생의 최댓값 return 
//여벌 체육복을 가져온 학생도 도난 가능,체육복을 빌려줄수 없음 하지만 자기것는 있음

bool reserve_check(int index, map<int,int>& students)
{
    //iter = 자신의 앞 또는 뒤 학생의 iter
    map<int,int>::iterator iter_before = students.find(index);
    
    //해당 학생이 없을수도 있기에(제일 앞학생 또는 제일 뒷학생 고려)
    //여벌 체육복이 있으면 해당 학생의 체육복을 -1 시킴
    if(iter_before  != students.end() && iter_before->second == 2)
    {
        iter_before->second--;
        return true;
    }  
    
    return false;
}


int solution(int n, vector<int> lost, vector<int> reserve) {
    int answer = 0;
    
    map<int,int> students; //학생번호,체육복 수
    
    //여벌 체육복이 있는 학생을 맵에 추가
    for(int num : reserve) {  students.insert({num,2}); }
    
    //체육복을 잃어버린 학생을 맵에 추가
    for(int num : lost)
    {
        //해당 맵에 여벌 체육복을 갖고 있지만 잃어버린 학생이 있을수 있기에 find 실행
         map<int,int>::iterator iter = students.find(num);
        //find결과가 없으면 해당 체육복이 없는 학생으로 추가
        if(iter  == students.end()) {  students.insert({num,0}); }
        //find 결과가 있으면 해당 학생의 체육복 수를 1감소
        else {  iter->second--;}
    }
    
    for(int i=1; i <= n ; i++)
    {
        map<int,int>::iterator iter = students.find(i);
        
        //해당 학생이 map에 없으면 수업을 들을 수 있기에 answer후 순회
        if(iter == students.end()) {  answer++;  continue;}
        
        //해당 학생이 체육복이 없는경우
        if(iter->second == 0)
        {
            //자기 앞,뒷 번호의 여벌 체육복을 체크후 true인경우 해당 학생의 체육복을 1증가
           if(reserve_check(i-1,students) || reserve_check(i+1,students))  iter->second++; 
        }
        
        //해당 학생이 체육복이 1개 이상인경우 answer증가 
        if(iter->second >=1) {  answer++; } 
        
    }

    
    
    return answer;
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

LV2.가장 큰 수  (0) 2023.11.03
LV1.둘만의 암호  (0) 2023.10.26
LV2.택배상자  (0) 2023.10.26
LV2.롤케이크 자르기  (0) 2023.10.26
LV2.숫자 변환하기  (0) 2023.10.26

https://school.programmers.co.kr/learn/courses/30/lessons/131704

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 내용 :

1.택배차가 원하는 택배번호 순서대로 택배를 실어야 함(인자값 : vector<int> order)

2.메인 컨테이너 벨트에 오름차순으로 택배가 존재하며,제일 앞에 택배만 꺼낼 수 있음

3.택배차에 짐을 실을때 원하는 택배가 아닌경우 서브 컨테이너 벨트에 택배를 보관할수 있음,

3-1.서브컨테이너 벨트는 제일 마지막에 쌓은 택배만 꺼낼 수 있음

4.두 벨트 에서 원하는 택배를 못 실을 경우 택배차는 출발함

이때 택배차에 몇개의 택배를 실을수 있는지 최대값을 찾는 문제 


풀이 : 

문제내용1 -> queue 자료구조에 적합 (순서대로 작업함에 따라 택배를 실고 삭제할때 앞에 원소 삭제하기가 용이함)

문제내용2 -> queue 자료구조에 적합

문제내용3 -> stack 자료구조에 적합

 

택배차의 queue<int> order를 순회하며 메인벨트(queue)와 서브벨트(stack)을 체크하며 answer의 값을 증가,

두 벨트에서 짐을 다 못 실을 경우 서브벨트에 택배를 쌓는다.

만약 메인벨트에서 더이상 서브벨트로 넣을 택배가 없으면  반복문에서 탈출하여 그대로 answer를 반환


코드 영역

더보기
#include <string>
#include <vector>
#include <queue>
#include <stack>

using namespace std;

//1.메인벨트와  적재 박스 비교
//2.같은경우 벨트와 적재박스 큐에서 제외 후 ,answer증가
//3.다른경우 서브벨트 top과 비교해서 같은경우 stack과queue에서 제외후 answer증가
//3.둘다 다른경우 서브벨트에 적재

int solution(vector<int> order) {
    int answer = 0;

    queue<int> q_order; // 기사님이 원하는 택배 순서
    queue<int> main_belt;// 메인 컨테이너벨트
    stack<int> sub_belt; // 서브 컨테이너벨트
    
    //택배차의 원하는 택배순서를 queue로 저장
    for (int i = 0; i < order.size(); i++)
    {
        main_belt.push(i + 1); 
        q_order.push(order[i]); 
    }

    while (!q_order.empty())
    {
        //메인 벨트의 택배와 택배차의 order list와 비교
        if (!main_belt.empty() && q_order.front() == main_belt.front())
        {
            answer++;
            q_order.pop();
            main_belt.pop();
        }
        //서브 벨트의 택배와 택배차의 order list와 비교
        else if (!sub_belt.empty() && q_order.front() == sub_belt.top())
        {
            answer++;
            q_order.pop();
            sub_belt.pop();
        }
        //메인 벨트의 서브 벨트 둘다 택배가 없는경우
        else
        {
            //메인 벨트에 택배가 있으면 서브벨트에 해당 택배를 보관 후 다시 순회
            if (!main_belt.empty())
            {
                sub_belt.push(main_belt.front());
                main_belt.pop();
            }
            //메인 벨트에 택배가 없으면 더이상 할 수 없으므로 탈출후 반환
            else { return answer; }
        }

    }

    return answer;
}

'코딩테스트 > 프로그래머스' 카테고리의 다른 글

LV1.둘만의 암호  (0) 2023.10.26
LV1.체육복  (0) 2023.10.26
LV2.롤케이크 자르기  (0) 2023.10.26
LV2.숫자 변환하기  (0) 2023.10.26
LV2.2개 이하로 다른 비트  (0) 2023.10.26

+ Recent posts