문제

접미사 배열 백준 11656번


리뷰

string STL 의 substr 을 쓰면 풀 수 있었다.

substr(i) 함수는 string의 i 인덱스 부터 마지막 인덱스까지 추출해준다.


코드

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main(void){

    vector<string> v;
     string S = "";
    cin >> S;

     for(int i = 0; i < S.size(); i++){
         string temp = S.substr(i); // 인덱스 i부터 끝까지 추출.
         v.push_back(temp);
    }

    sort(v.begin(), v.end()); // 정렬 

    for(int i = 0; i < S.size(); i++){ // 출력 
        cout << v[i] << '\n';
    }

    return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

단어뒤집기 백준 9093번  (0) 2020.08.27
문자열 분석 백준 10820번  (0) 2020.08.27
네 수 백준 10824  (0) 2020.08.27
ROT13 백준 11655  (0) 2020.08.27
에디터 백준 1406번 c++  (0) 2020.08.26

문제

네 수 백준 10824번


리뷰

10 과 20 을 이어붙여서 1020가 된다면, 1000 + 20 과도 같다.

따라서 20의 자리 수 만큼(2만큼) 10에 10을 2번 곱해주면 1000이 된다.

A, B, C, D 를 입력받는데, B와 D의 자리수만 알면 된다.

    while(tempB > 0){ // B의 자리수 센다
        tempB /= 10;
        B_len++;
    }

B의 자리수를 알아냈으면, pow() 함수를 이용해서 10을 2번 곱해준다.

그리고 A에 더한다.

A = A * pow(10, B_len) + B;

문제해결 과정

pow() 함수를 쓸 때는 반드시 cmath 를 include 해 줘야 한다!

안그러면 컴파일 에러가 난다...

(1 ≤ A, B, C, D ≤ 1,000,000) 숫자의 크기가 크다. 도움이 된 질문게시판 글

네 수 모드 100만이면, 답이 int 형의 범위를 넘는다. 따라서 long long 자료형으로 선언해야 한다.


코드

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

// 10824 네 수 

long long A, B, C, D;
long long answer;

int main(void){

    cin >> A >> B >> C >> D;

    int B_len=0, D_len = 0;
    long long tempB = B, tempD = D;

    while(tempB > 0){ // B의 자리수 센다
        tempB /= 10;
        B_len++;
    }

    while(tempD > 0){ // D의 자리수 센다
        tempD /= 10;
        D_len++;
    }

    A = A * pow(10, B_len) + B;
    C = C * pow(10, D_len) + D;

    answer = A+C;

    cout << answer;

    return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

문자열 분석 백준 10820번  (0) 2020.08.27
접미사 배열 백준 11656번  (0) 2020.08.27
ROT13 백준 11655  (0) 2020.08.27
에디터 백준 1406번 c++  (0) 2020.08.26
스택 수열 백준 1874번  (0) 2020.08.26

문제

ROT13 백준 11655번

리뷰

아스키 코드를 이용해서 풀었다.

공백은 32 , 숫자는 '0'과 '9'는 48 ~ 57. 대문자 65 ~ 90, 소문자 97 ~ 122 이다.

찾아보니까 대소문으로 조건으로 비교하기 보다는

if(st[i] <= 'A' && st[i] <= 'Z'){} // 대문자 

else if(st[i] <= 'a' && st[i] <= 'z'){} // 소문자      

string STL에 있는 islower 와 isupper를 쓰면 간결하게 짤 수 있었다.

코드

영 맘에 안들지만 내가 처음에 맞은 코드다.

#include <iostream>
#include <string>
using namespace std;

int main(void){

     string st;

     getline(cin, st);

     for(int i = 0; i < st.size(); i++){

         if(st[i] == ' ') cout << ' ';
         else if(st[i] <= '9'){
             cout << st[i];
        }
         else if(st[i] <= 'Z'-13){ // 대문자  
            st[i] += 13; 
            cout << st[i];
        }else if(st[i] <= 'Z'){
            st[i] = st[i] + 13 - 26;  
            cout << st[i];
        }else if(st[i] <= 'z'-13){ // 소문자  
            st[i] += 13; 
            cout << st[i];
        }else{
            st[i] = st[i] + 13 - 26;
            cout << st[i];
        }

    }

    return 0;
}

코드2

질문게시판의 다른 분들의 코드를 보며 고쳐본 코드다.

#include <iostream>
#include <string>
using namespace std;

int main(void){

     string st;
     getline(cin, st);
     int len = st.length();

     for(int i = 0; i < len; i++){

         if(isupper(st[i])){ // 대문자 

            if(st[i] + 13 > 'Z') st[i] = st[i]+13-26;
            else st[i] += 13;

        }else if(islower(st[i])){ // 소문자 

            if(st[i] + 13 > 'z') st[i] = st[i]+13-26;
            else st[i] += 13;         
        }
        cout << st[i];
    }

    return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

접미사 배열 백준 11656번  (0) 2020.08.27
네 수 백준 10824  (0) 2020.08.27
에디터 백준 1406번 c++  (0) 2020.08.26
스택 수열 백준 1874번  (0) 2020.08.26
2007년 백준 1924번  (0) 2020.08.25

에디터 백준 1406번

 

리뷰

스택 2개를 이용해 풀었다.

커서를 기준으로 왼쪽에 있는 문자들은 왼쪽 스택에, 오른쪽에 있는 문자들은 오른쪽 스택에 넣는다.

커서를 기준으로 문자를 삭제하거나 삽입하거나 하기 때문에 stack을 활용할 수 있었다.

 

커서를 오른쪽으로 옮기는 연산은, 왼쪽 스택의 top을 오른쪽 스택에 push 하는 것이다.

커서를 왼쪽으로 옮기는 연산은, 오른쪽 스택의 top을 왼쪽 스택에 push 하는 것이다.

 

문제 해결 과정 

 

처음에는 런타임 에러가 났다. 고치다가 안되니까 1406번 문제 질문 게시판을 찾아봤다.

stack에서 pop 하기 전에 empty() 함수로 스택이 비었는지를 확인했어야 했다. 도움된 글

 

empty() 조건을 추가했더니, 이번에는 시간 초과가 났다.

이유는 결과 출력을 할 때, 스택에서 꺼낸 문자들을 string에 이어붙여가면서 했기 때문이었다.

 

왼쪽 스택에 있던 문자를 전부 오른쪽 스택으로 옮기고.

오른쪽 스택을 top 부터 빌때까지 전부 출력하면 시간 초과가 나지 않고 맞출 수 있었다.

 

코드

#include <iostream>
#include <stack>
#include <string>
using namespace std;

int main(void){

    stack<char> st_L, st_R; // 커서 기준으로 왼쪽 스택, 오른쪽 스택. 
    int M;
    string answer;

    cin >> answer >> M; // 초기 문자열과 명령어 횟수 입력받기 

    // 초기에 주어진 문자열을 전부 왼쪽 스택에 넣는다.  
    for(int i = 0; i < answer.size(); i++){
        st_L.push(answer[i]);
    }

    while(M--){ // 명령어 횟수 만큼 수행 

        char order, ch;
        cin >> order; // 명령어 입력받기 

        if(!st_L.empty() && (order == 'L') ){ // 왼쪽 스택의 top을 오른쪽 스택에 push

            ch = st_L.top();
            st_R.push(ch);
            st_L.pop();

        }else if(!st_R.empty() && (order == 'D') ){ // 오른쪽 스택의 top을 왼쪽 스택에 push

            ch = st_R.top();
            st_L.push(ch);
            st_R.pop();

        }else if(!st_L.empty() && (order == 'B') ){ // 왼쪽 스택을 pop 하면 top을 삭제한 셈.

            st_L.pop();

        }else if(order == 'P'){ // 문자를 받아서 왼쪽에 삽입

            cin >> ch;
            st_L.push(ch);
        }        
    }

    // 문자열을 처음부터 출력하기 위해, 
    // 왼쪽에 있는 문자들을 전부 오른쪽 스택으로 옮기기.
    while(!st_L.empty()){
        st_R.push(st_L.top());
        st_L.pop();
    }

    while(!st_R.empty()){ // 최종 출력 
        cout << st_R.top();
        st_R.pop();
    }
    return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

네 수 백준 10824  (0) 2020.08.27
ROT13 백준 11655  (0) 2020.08.27
스택 수열 백준 1874번  (0) 2020.08.26
2007년 백준 1924번  (0) 2020.08.25
열 개씩 끊어 출력하기 백준 11721번  (0) 2020.08.25

문제

스택 수열 백준 1874번


리뷰

문제 맨 밑에 '힌트'를 읽고 이해 했다.

1부터 n 까지 수에 대해서는 반드시 push n번, pop n번이 수행되야 목표수열을 얻을 수 있다.

만약, 스택에 숫자가 남아있으면, 실패니까 "NO" 를 출력해야 한다.


1부터 n 까지 수를 차례로 push 한다.

for(i=1; i<=num; i++){ // 1 부터 n 까지 수는 반드시 들어온다. 

        st.push(i);
        answer.push_back('+');
}

그러나 pop을 하려면 스택의 top이 목표수열의 숫자와 일치하는지 계속 확인해줘야 한다. 그래서 while문으로 만들었다.


pop을 할 때는 목표 수열의 다음숫자를 타겟으로 해야하니까 목표수열의 인덱스도 증가시켜줘야 한다는게 중요하다.

스택이 비어있으면 pop도 불가하니까, empty() 함수로 스택이 비었는지 확인한다.

for(i=1; i<=num; i++){ // 1 부터 n 까지 수는 반드시 들어온다. 

        st.push(i);
        answer.push_back('+');

        while(!st.empty() && (st.top() == N[idx])){ // 수열의 숫자와 같으면, pop

            st.pop();
            answer.push_back('-');
            idx++; // 목표 수열의 인덱스도 증가시켜준다. 
        } 

}

예를 들어, 입력받은 수열크기는 8이다. 목표 수열은 4 3 6 8 7 5 2 1 이다.

목표 수열은 4 3 6 8 7 5 2 1 이다.  (현재는 idx = 0, N[idx] = 4 를 타겟으로 한다. )

1, 2, 3, 4 순으로 push 했다. (위의 코드로 보면 i가 4까지 진행된 상태다)

여기서 목표수열의 첫번째 숫자 4와 스택의 top 4 가 같아진다. 즉, while 문의 조건을 충족한다. 
pop 한다. 
목표수열의 다음 숫자 3 과 스택의 top 3이 또 같아진다.  
(idx = 1로 바뀌면서 N[idx] = 3 이 된다. )
pop 한다. 

다시 5, 6 순으로 push 한다. 
while 문의 조건을 다시 확인한다. 

**코드

#include <iostream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

int N[100001]; // 입력받은 수열  
vector<char> answer; // 출력할 +, - 담을 벡터  
stack<int> st;

int main(void){

    freopen("input.txt", "rt", stdin);

     int i, idx, num = 0;

     scanf("%d", &num); // num 이하의 수열을 입력받자. 

    for(i=0; i<num; i++){ // 목표 수열 입력받기 
        scanf("%d", &N[i]); 
    }  // 입력받기 끝  


    // answer에는 push 할 때 '+'를 넣고, pop 할 때 '-'를 넣는다.  

    for(i=1; i<=num; i++){ // 1 부터 n 까지 수는 반드시 들어온다. 

        st.push(i);
        answer.push_back('+');

        while(!st.empty() && (st.top() == N[idx])){ // 수열의 숫자와 같으면, pop

            st.pop();
            answer.push_back('-');
            idx++; // 목표 수열의 인덱스도 증가시켜준다. 
        } 

    }

    if(!st.empty()) printf("NO"); // 스택에 뭐가 남았다면 실패니까 "NO"
    else{
        for(i=0; i<answer.size(); i++){ // answer 에 담았던 문자들 순차출력 
            printf("%c\n", answer[i]);
        }   
    } 

     return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

ROT13 백준 11655  (0) 2020.08.27
에디터 백준 1406번 c++  (0) 2020.08.26
2007년 백준 1924번  (0) 2020.08.25
열 개씩 끊어 출력하기 백준 11721번  (0) 2020.08.25
그대로 출력하기 백준 11718번 c++  (0) 2020.08.24

문제

2007년 백준 1924번


리뷰

1년 전에 풀었던 건데, 다시 풀어봤다.

달 마다의 일 수는 M배열에 넣는다.

7로 나누었을 때 나머지로 요일을 구분해 출력할 문자열을 D배열에 넣어둔다.

입력이 3월 14일 이면, 14에 1월의 총 일수, 2월의 총 일수를 더한다. 3월은 안 더한다.

7로 나눈 나머지에 따라서 요일이 정해진다.


코드

#include <iostream>
using namespace std;

int main(void){

    int M[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
    string D[8] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

    int A, B = 0;
    int day = 0;

    cin >> A >> B;

    day = B;

    for(int i = 1; i < A; i++){
        day += M[i];
    }

    cout << D[day % 7];

     return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

에디터 백준 1406번 c++  (0) 2020.08.26
스택 수열 백준 1874번  (0) 2020.08.26
열 개씩 끊어 출력하기 백준 11721번  (0) 2020.08.25
그대로 출력하기 백준 11718번 c++  (0) 2020.08.24
정수 삼각형 백준 1932  (0) 2020.08.22

문제

열 개씩 끊어 출력하기 백준 11721번


리뷰

인덱스가 10번째가 됬을 때 마다 개행문자를 출력하려고 했었는데, 잘 안됬다.

다른 분들 코드를 보면서 scanf 함수에서 특정 길이까지 읽어들일 수 있는 서식문자가 있다는 것을 알게됬다!


scanf 의 서식문자

scanf의 서식문자로는 c 문자, s 문자열, p 포인터, d 10진 정수 등 이 있다.

%와 서식문자는 반드시 명시해야 한다.

그리고 폭을 지정하거나 포인터의 형을 지정할 수 있는 등의 옵션이 있다.

#include <stdio.h>

int scanf(const char *format [,address ...]);
  • 폭 지정

    %와 서식 문자 사이에 정수값을 삽입하면, 입력값 중 읽어들일 최대 길이를 지정할 수 있다.

    scanf("%10s", &A);
  • 검색 문자 지정 (search_set)

    배열 주소에서, 특정 조건에 따라 읽어들이는 방법을 제공한다.

    [ ] 안에 쓴 문자들만 읽어들여 입력받는다. 즉, h, i, j, k 문자들만 입력받는다.

    이외의 문자들이 입력되면 입력을 중단한다.

    문자 맨 앞에 ^ 기호를 붙이면, x, y, z를 제외한 문자들만 입력받는다.

    char A[102];
    
    scanf("%[hijk]", A);
    
    scanf("%[^xyz]");

코드

#include <iostream>
using namespace std;

char A[102];

int main(void){

    while(scanf("%10s", &A) != EOF){
        printf("%s\n", A);
    }

    return 0;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

스택 수열 백준 1874번  (0) 2020.08.26
2007년 백준 1924번  (0) 2020.08.25
그대로 출력하기 백준 11718번 c++  (0) 2020.08.24
정수 삼각형 백준 1932  (0) 2020.08.22
연속합2 백준 13398  (0) 2020.08.22

+ Recent posts