프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <string>
#include <vector>
 
using namespace std;
 
int solution(int n, vector<int> lost, vector<int> reserve) 
{
    int answer = n - lost.size();
    int iSize = reserve.size();
    
    //여벌을 가진사람중에 잃어버린 사람이 있는지
    for(auto& a : reserve)
    {
        for(auto& b : lost)
        {
            if(a==b)
            {
                answer++;
                a = -10;
                b = -1;
            }
        }
    }
    
    
    for(int i = 0 ; i < iSize ; i++)
    {
        
        for(int k = 0 ; k < lost.size() ; k++)
        {
            //여벌을 가진사람이 누구에게 빌려줄수
            if(reserve[i] -1 == lost[k] || reserve[i] +1 == lost[k])
            {
                answer++;
                reserve[i] = -10;
                lost[k] = -1;
            }
        }
    }
    
    
    return answer;
}
 

1. 전체 인원수에서 잃어버린 사람들의 수를 먼저 계산한다.

2. 여벌을 가진 목록과 잃어버린 사람 목록에 동일한 사람이 있는지 확인

3. 남은 사람들중 빌려줄 수 있는 체육복을 가진 사람을 확인

 

for문을 분리한 이유는 n = 10, lost = [3,9,10] reserve = [3,8,9]

같은 경우를 방지하기 위해서이다.

값을 수정한 이유는 삭제로인한 벡터의 재할당보다 값 변경이 싸게 먹힐거라 생각했기 때문이다.

 -> 벡터 컨테이너의 Capcity를 할당하면 삭제로 인한 재할당은 없을 것이다.

프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <algorithm>
 
using namespace std;
 
int solution(vector<int> d, int budget) {
    int answer = 0;
    int sum = 0;
    
    sort(d.begin(), d.end());
    
    for(int i = 0 ; i < d.size() ; i++)
    {
        if(sum + d[i] > budget)
            break;
        
        sum += d[i];
        answer++;
    }
    
    return answer;
}
 

알고리즘의 sort함수를 이용하면 쉽게 풀 수 있다.

프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <string>
#include <vector>
 
using namespace std;
 
vector<long long> solution(int x, int n) {
    vector<long long> answer;
    answer.reserve(n);
    
    for(int i = 0 ; i < n ; i++)
        answer.emplace_back(x * (i + 1));
    
    return answer;
}
 

굳이 포스팅할 문제는 아니지만, vector를 미리 reserve() 하고 사용하면, 컨테이너용량이 늘어날때 벡터의 capacity가 재할당 되기때문에 이를 방지한다는 것을 알리려고 포스팅했다.

프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string>
#include <vector>
 
using namespace std;
 
vector<vector<int>> solution(vector<vector<int>> arr1, vector<vector<int>> arr2) 
{
    vector<vector<int>> answer(arr1.size(), vector<int>(arr1[0].size(), 0));
    
    for(int i = 0 ; i < arr1.size() ; i++)
    {
        for(int j = 0 ; j < arr1[0].size() ; j++)
        {
            answer[i][j] = arr1[i][j] + arr2[i][j];
        }
    }
    
    return answer;
}
 

그냥 행렬의 덧셈이다.

벡터를 생성과 동시에 초기화하면 capacity가 변하지 않는다.

 

fill constructor (벡터 생성자 초기화)

각 원소에 할당된 값이 있는 n개의 원소를 가진 컨테이너를 생성합니다.

 

시간 복잡도

O(n)

 

선언

vector<자료형> 컨테이너이름(n, value);

n 컨테이너의 크기

value 컨테이너의 각 원소에 할당될 값



출처: https://woodforest.tistory.com/206 [나무 숲]

프로그래머스 레벨 1 테스트

내가 푼것.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <string>
#include <vector>
 
using namespace std;
 
vector<int> solution(vector<int> arr) 
{
    int Min = arr[0];
    int Index = 0;
    
    if(arr.size() == 1)
    {
        arr[0= -1;
        return arr;
    }
    
    for(int i = 1 ; i < arr.size() ; i++)
    {
        Index = (Min > arr[i]) ? i : Index;
        Min = min(Min, arr[i]);
    }
    
    arr.erase(arr.begin() + Index);
    
    return arr;
}
 

algorithm 헤더에는 배열에서 가장 작은 값과 가장 큰 값을 찾아주는 함수가 있다.

min_element(), max_element()이다.

min_element(배열시작, 배열끝); 으로 사용하며, 반환값은 값이 들어있는 주소다.

 

min_element()를 알게되고 수정한 것

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <string>
#include <vector>
#include <algorithm>
 
using namespace std;
 
vector<int> solution(vector<int> arr) 
{
    vector<int>::iterator iter = arr.begin();    
    
    iter = min_element(arr.begin(), arr.end());
    arr.erase(iter);
    
    if(arr.empty())
        arr.emplace_back(-1);
    
    return arr;
}
 

min_element()와 이터레이터(반복자)를 이용해 이렇게 풀어낼수도 있다.

프로그래머스 레벨 1 테스트

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#include <vector>
#include <algorithm>
 
using namespace std;
 
long long solution(long long n) 
{
    long long answer = 0;
    vector<int> vecAnswer;
    string str = to_string(n);
    
    for(int i = 0 ; i < str.size() ; i++)
        vecAnswer.emplace_back(str[i] - '0');
    
    sort(vecAnswer.begin(), vecAnswer.end());
    
    for(int i = 0 ; i < vecAnswer.size() ; i++)
        answer += vecAnswer[i] * pow(10, i);
        
    return answer;
}
 

내림차순 정렬 후 벡터의 순서대로 pow를 이용해 정답에 집어 넣었다.

프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <vector>
 
using namespace std;
 
vector<int> solution(long long n) {
    vector<int> answer;
    
    while(n > 0)
    {
        answer.emplace_back(n % 10);
        n /= 10;
    }
    
    return answer;
}
 

자연수를 뒤집지 않고 배열로 만든다면 string으로 변환해서 앞에서부터 숫자로 배열에 집어 넣으면 된다.

프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
using namespace std;
int solution(int n)
{
    int answer = n % 10;
        
    for(int i = 10 ; ; i *= 10 )
    {
        if(i > n)
            break;
        
        int Numb = n / i;
        answer += Numb % 10;
    }
    
    return answer;
}
 

직접 푼것.

 

while (n > 0)

{

    answer += n % 10;

    n /= 10;

}

 

while을 활용한 방법도 있다.

 

모범답안

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
 
using namespace std;
int solution(int n)
{
    int answer = 0;
 
    string s = to_string(n);
 
    for(int i = 0; i < s.size(); i++)
        answer += (s[i] - '0');
 
    return answer;
}
 

스트링을 이용해서 푸는 것은 생각했으나 ascii 코드를 활용해 푸는 것은 생각못해서 가져온 모범답안.

ascii 코드로 숫자는 '0'(48) 이후의 숫자이기 문자열에서 '0'을 빼주면 숫자로 변환된다.

 

프로그래머스 레벨 1 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <string>
#include <vector>
 
using namespace std;
 
string solution(string s) {
    string answer = "";
    string strTmp = "";
    
    for(int i = 0 ; i < s.size() ; i++)
    {
 
        
        if(isspace(s[i]))
        {
            for(int j = 0 ; j < strTmp.size() ; j++)
            {
                if ((j % 2== 0 && islower(strTmp[j]))
                    strTmp[j] = toupper(strTmp[j]);
                else if((j % 2!= 0 && isupper(strTmp[j]))
                    strTmp[j] = tolower(strTmp[j]);
            }
            answer += strTmp;
            answer += " ";
            strTmp.clear();
        }
        else
            strTmp += s[i];
        
        if(i == s.size()-1)
        {
            for(int j = 0 ; j < strTmp.size() ; j++)
            {
                if ((j % 2== 0 && islower(strTmp[j]))
                    strTmp[j] = toupper(strTmp[j]);
                else if((j % 2!= 0 && isupper(strTmp[j]))
                    strTmp[j] = tolower(strTmp[j]);
            }
            answer += strTmp;
            strTmp.clear();
        }
        
    }
    
    return answer;
}
 

의사코드

1. 공백이 나올때까지 문자열을 검사하며 수집한다.

2. 공백이 나오면 문자열을 저장하고 사이즈를 측정해 % 2 나머지가 0인것을 대문자로 변환한다.

3. 문자열이 대소문자 섞여서 나올 수 있기때문에 소문자인지 대문자인지 검사한 후 변환한다.

4. 정렬되면 정답 배열에 집어 넣는다.

 

// 수정 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <string>
#include <vector>
 
using namespace std;
 
string solution(string s) 
{
    string answer = "";
    
    //문장의 시작을 홀수로 만듬
    int oddeven = 1;
    for (int i = 0; i < s.size(); i++)
    {
        if (isspace(s[i]))
        {
            answer += " ";
            //공백인 경우 짝수부터 문장 시작
            oddeven = 1;
            continue;
        }
 
        if (oddeven == 1 && islower(s[i]))
        {
            answer += toupper(s[i]);
            oddeven--;
            continue;
        }
        else if (oddeven == 0 && isupper(s[i]))
        {
            answer += tolower(s[i]);
            oddeven++;
            continue;
        }
 
        answer += s[i];
        //현재 문장의 홀짝 구분
        oddeven = (oddeven == 0) ? 1 : 0;
    }
    
    return answer;
}
 

if문과 for문이 너무 많이 들어가서 수정.

만약 isupper, toupper 같은 함수를 사용할 수 없다면

ascii 코드를 이용해 대소문자 확인 후 변경해주는식으로 코드를 짤 수 있다.

프로그래머스 레벨2 테스트

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <string>
#include <vector>
 
using namespace std;
 
string TentoBinString(int iBin, int iSize)
{
    string strTmp = "";
    string answer = "";
    for(int i = 0 ; i < iSize ; i++)
    {
        int num = iBin % 2;
        
        if(num == 0)
            strTmp += " ";
        else
            strTmp += "#";
        
        iBin *= 0.5;
    }
    //string에 비트연산이 뒤집혀 들어가기때문에 
    for(int i = 0 ; i < iSize ; i++)
        answer += strTmp[iSize -1 -i];
    
    return answer;
}
 
vector<string> solution(int n, vector<int> arr1, vector<int> arr2) 
{
    vector<string> answer;
    answer.reserve(n * n);
    
    for(int i = 0 ; i < n ; i++)
    {
        //or연산
        int iBin = arr1[i] | arr2[i];
        answer.emplace_back(TentoBinString(iBin, n));
    }
        
    return answer;
}
 

의사코드

1. 두 배열의 값을 OR 연산한다.

2. OR 연산한 값을 2진법으로 변환하며 0과 1을 공백과 #으로 변환한다.

3. string에 입력될 때 역순으로 들어가기 때문에 연산 종료 후 배열을 뒤집는다.

4. 맵의 크기 만큼 반복해서 배열을 완성한다.

 

 

// 수정한 풀이법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <string>
#include <vector>
 
using namespace std;
 
string TentoBinString(int iBin, int iSize)
{
    string answer = "";
 
    for(int i = 0 ; i < iSize ; i++)
    {
        int num = iBin % 2;
        
        if(num == 0)
            answer = " " + answer;
        else
            answer = "#" + answer;
        
        iBin >>= 1;
    }
    
    return answer;
}
 
vector<string> solution(int n, vector<int> arr1, vector<int> arr2) 
{
    vector<string> answer;
    answer.reserve(n * n);
    
    for(int i = 0 ; i < n ; i++)
    {
        //or연산
        int iBin = arr1[i] | arr2[i];
        answer.emplace_back(TentoBinString(iBin, n));
    }
        
    return answer;
}
 

 answer = " " + answer; 같은 방법으로 역순으로 들어오는 값을 정방향으로 넣을 수 있었다.

 

+ Recent posts