시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초256 MB68533142011143925.778%

문제

입력 받은 대로 출력하는 프로그램을 작성하시오.

입력

입력이 주어진다. 입력은 최대 100줄로 이루어져 있고, 알파벳 소문자, 대문자, 공백, 숫자로만 이루어져 있다. 각 줄은 100글자를 넘지 않으며, 빈 줄은 주어지지 않는다. 또, 각 줄은 공백으로 시작하지 않고, 공백으로 끝나지 않는다.

출력

입력받은 그대로 출력한다.

예제 입력 1 

Hello
Baekjoon
Online Judge

예제 출력 1 

Hello
Baekjoon
Online Judge




<풀이과정> 


1. C++ 언어를 이용한 풀이 


문자열을 통채로 저장하는 string 자료형을 사용한다. 

한 줄을 입력받아 저장할 수 있는 getline 함수를 사용 

whille(true)로 설정하여 무한 루프를 만들고 입력값이 공백일 때 루프를 빠져나가도록 한다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
#include<string>
using namespace std;
 
int main(){
 
    string str;
    while (true)
    {
        getline(cin, str);
        if (str=="")
            break;
        cout << str << endl;
    }
 
    return 0;
}
cs



2. C언어를 이용한 풀이


한 줄에 받을 수 있는 최대 100글자의 배열을 char 자료형의 배열로 만들어 저장한다. 

줄바꿈을 제외하고 한 줄로 입력받고 한 줄을 문자형 배열로 입력받는다. 

입력이 제대로 되었으면 계속 반복 여기서는 루프를 빠져나가는 탈출 조건을 따로 주지 않았다. 


1
2
3
4
5
6
7
8
#include <cstdio>
char s[101];
int main() {
    while (scanf("%[^\n]\n",s)==1) {
        printf("%s\n",s);
    }
    return 0;
}
cs



둘다 정답!!

코드의 효율은 C언어를 사용한 것이 더 좋은 모습




시간 제한메모리 제한제출정답맞은 사람정답 비율
2 초128 MB80943126266039.425%

문제

전자 제품에는 저항이 들어간다. 저항은 색 3개를 이용해서 그 저항이 몇 옴인지 나타낸다.

처음 색 2개는 저항의 값이고, 마지막 색은 곱해야 하는 값이다.

저항의 값은 다음 표를 이용해서 구한다.

black01
brown110
red2100
orange31000
yellow410000
green5100000
blue61000000
violet710000000
grey8100000000
white91000000000

예를 들어, 저항에 색이 yellow, violet, red였다면 저항의 값은 4,700이 된다.

입력

첫째 줄에 첫번째 색, 둘째 줄에 두번째 색, 셋째 줄에 세번째 색이 주어진다. 색은 모두 위의 표에 써 있는 색만 주어진다.

출력

첫째 줄에 입력을 주어진 저항의 저항값을 출력한다.

예제 입력 1 

yellow
violet
red

예제 출력 1 

4700



<풀이과정> 


아래 처음 코드는 

자료형을 제대로 사용하지 않아 틀렸다..

아래 코드는 최대값을 입력했을 때 오류를 일으킨다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
    map<stringpair<int,int>> d1={
    {"black",{0,1}},{"brown",{1,10}},{ "red",{ 2,100 } },
    { "orange",{ 3,1000 } },{ "yellow",{ 4,10000 } },{ "green",{ 5,100000 } },
    { "blue",{ 6,1000000 } },{ "violet",{ 7,10000000 } },
    { "grey",{ 8,100000000 } },{ "white",{ 9,1000000000 } }};
    
    string a,b,c;
    cin >> a >> b >> c; // 숫자 텍스트 
    string s1,s2,ss;
    s1 = to_string(d1[a].first); 
    s2 = to_string(d1[b].first);
    ss = s1+s2;
    cout << stoi(ss)*d1[c].second;
    
  
    
    return 0;
}
cs




문제에서 나올 수 있는 최대 저항의 값은 

가장 큰 곱셉값인 10억 * 처음색 두개 두자리수 -> 백억단위 이상

문제의 조건을 보면 음수 값은 나올 수 없다.


--> unsigned long long 자료형 사용 



<c++ 자료형 범위와 크기 비교>

char 
signed char
1바이트, 8비트-128~127 
unsigned char1바이트, 8비트0~255 
short 
short int
2바이트, 16비트-32,768~32,767int 생략 가능
unsigned short 
unsigned short int
2바이트, 16비트0~65,535int 생략 가능
int
signed int
4바이트, 32비트-2,147,483,648~ 2,147,483,647 
unsigned 
unsigned int
4바이트, 32비트0~4,294,967,295int 생략 가능
long
long int
signed long
signed long int
4바이트, 32비트-2,147,483,648~ 2,147,483,647int 생략 가능
unsigned long 
unsigned long int
4바이트, 32비트0~4,294,967,295int 생략 가능
long long 
long long int 
signed long long 
signed long long int
8바이트, 64비트-9,223,372,036,854,775,808~
9,223,372,036,854,775,807
int 생략 가능
unsigned long long 
unsigned long long int
8바이트, 64비트0~18,446,744,073,709,551,615int 생략 가능



<최종코드>


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
    map<stringpair<int,int>> d1={
    {"black",{0,1}},{"brown",{1,10}},{ "red",{ 2,100 } },
    { "orange",{ 3,1000 } },{ "yellow",{ 4,10000 } },{ "green",{ 5,100000 } },
    { "blue",{ 6,1000000 } },{ "violet",{ 7,10000000 } },
    { "grey",{ 8,100000000 } },{ "white",{ 9,1000000000 } }};
    
    string a,b,c;
    cin >> a >> b >> c; // 숫자 텍스트 
    string s1,s2,ss;
    s1 = to_string(d1[a].first); 
    s2 = to_string(d1[b].first);
    ss = s1+s2;
    
    unsigned long long number = stoi(ss); // 저항값
    cout << number*d1[c].second;
    
    return 0;
}
cs





정답!

















시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초256 MB2788410864830940.152%

문제

정수를 저장하는 스택을 구현한 다음, 입력으로 주어지는 명령을 처리하는 프로그램을 작성하시오.

명령은 총 다섯 가지이다.

  • push X: 정수 X를 스택에 넣는 연산이다.
  • pop: 스택에서 가장 위에 있는 정수를 빼고, 그 수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.
  • size: 스택에 들어있는 정수의 개수를 출력한다.
  • empty: 스택이 비어있으면 1, 아니면 0을 출력한다.
  • top: 스택의 가장 위에 있는 정수를 출력한다. 만약 스택에 들어있는 정수가 없는 경우에는 -1을 출력한다.

입력

첫째 줄에 주어지는 명령의 수 N (1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄부터 N개의 줄에는 명령이 하나씩 주어진다. 주어지는 정수는 1보다 크거나 같고, 100,000보다 작거나 같다. 문제에 나와있지 않은 명령이 주어지는 경우는 없다.

출력

출력해야하는 명령이 주어질 때마다, 한 줄에 하나씩 출력한다.

예제 입력 1 

14
push 1
push 2
top
size
empty
pop
pop
pop
size
empty
pop
push 3
empty
top

예제 출력 1 

2
2
0
2
1
-1
0
1
-1
0
3



<풀이과정>


명령어의 수 만큼 반복되는 루프 만들고 

명령어를 입력 받아 if문을 통해 명령어를 확인

명령어가 확인되면 해당하는 명령어의 기능을 수행한다. 



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
47
48
49
50
51
#include<iostream>
#include<string>
#include<stack> 
using namespace std;
 
int main(){
    int N;
    cin >> N; // 명령의 수
    stack<int> s; // 스택 
     
    while(N--){
        string cmd; //명령어  
        cin >> cmd; // 명령어 입력
        if(cmd=="push"){
            int x; // 스택에 넣을 정수
            cin >> x;
            s.push(x); // 스택에 정수를 추가  
        } 
        else if(cmd=="pop"){
            if(s.empty()){
                cout << "-1" <<"\n";
            }
            else{
                cout << s.top() <<"\n";
                s.pop();
            }
        }
        else if(cmd=="size"){
            cout << s.size() <<"\n";
        }
        else if(cmd=="empty"){
            if(s.empty()){
                cout << "1" <<"\n";
            }
            else{
                cout << "0" <<"\n";
            }
        }
        else if(cmd=="top"){
            if(s.empty()){
                cout << "-1" <<"\n";
            }
            else{
                cout << s.top() << "\n";
            }
        }
        
    }
 
    return 0;
}
cs


시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초128 MB233309175692139.391%

문제

괄호 문자열(Parenthesis String, PS)은 두 개의 괄호 기호인 ‘(’ 와 ‘)’ 만으로 구성되어 있는 문자열이다. 그 중에서 괄호의 모양이 바르게 구성된 문자열을 올바른 괄호 문자열(Valid PS, VPS)이라고 부른다. 한 쌍의 괄호 기호로 된 “( )” 문자열은 기본 VPS 이라고 부른다. 만일 x 가 VPS 라면 이것을 하나의 괄호에 넣은 새로운 문자열 “(x)”도 VPS 가 된다. 그리고 두 VPS x 와 y를 접합(concatenation)시킨 새로운 문자열 xy도 VPS 가 된다. 예를 들어 “(())()”와 “((()))” 는 VPS 이지만 “(()(”, “(())()))” , 그리고 “(()” 는 모두 VPS 가 아닌 문자열이다. 

여러분은 입력으로 주어진 괄호 문자열이 VPS 인지 아닌지를 판단해서 그 결과를 YES 와 NO 로 나타내어야 한다. 

입력

입력 데이터는 표준 입력을 사용한다. 입력은 T개의 테스트 데이터로 주어진다. 입력의 첫 번째 줄에는 입력 데이터의 수를 나타내는 정수 T가 주어진다. 각 테스트 데이터의 첫째 줄에는 괄호 문자열이 한 줄에 주어진다. 하나의 괄호 문자열의 길이는 2 이상 50 이하이다. 

출력

출력은 표준 출력을 사용한다. 만일 입력 괄호 문자열이 올바른 괄호 문자열(VPS)이면 “YES”, 아니면 “NO”를 한 줄에 하나씩 차례대로 출력해야 한다. 

예제 입력 1 

6
(())())
(((()())()
(()())((()))
((()()(()))(((())))()
()()()()(()()())()
(()((())()(

예제 출력 1 

NO
NO
YES
NO
YES
NO



<풀이과정>


첫번째 틀린 풀이 


문자열을 입력받고 '(' 가 나오면 스택에 추가하고 ')'가 나오면 스택에서 삭제하는 방식으로 설계했다. 

그래서 스택이 최종적으로 비어있으면 YES, 스택에 무언가 남아있으면 NO를 출력하게 하였다. 


그러나 이 방식의 문제점은 ')'가 먼저 나오는 경우에 대해서 오류를 잡아내지 못했다. 

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
#include<iostream>
#include<string>
#include<stack> 
using namespace std;
 
int main(){
    int N;
    cin >> N; // 명령의 수
 
    while(N--){
        stack<char> s; // 스택 
        string PS; //괄호 문자열   
        cin >> PS;
        for(int i=0;i<N;i++){
            if(PS[i]=='('){
                s.push(PS[i]);
            }
            else if (PS[i]==')'){
                s.pop();
            }
        }
        if(s.empty()){
            cout << "YES" << "\n";
        }
        else{
            cout << "NO" <<"\n";
        }
    }
    return 0;
}
cs

두 번째 틀린 풀이 

그래서 생각한 것이 변수를 만들어 여는 괄호가 나오면 +1 하고 
닫는 괄호가 나오면 -1을 해줘서
마지막에 0이 되는 경우만 YES를 출력한다.

이 코드의 문제점은 '())(' 다음과 같은 문자열의 오류를 찾아내지 못한다. 
여는 괄호와 닫는 괄호의 숫자만 같으면 바른 괄호문자로 인식한다.   
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
#include<iostream>
#include<string>
using namespace std;
 
int main(){
    int N;
    cin >> N; // 명령의 수
 
    while(N--){
        int chk=0
        string PS; //괄호 문자열   
        cin >> PS;
        for(int i=0;i<N;i++){
            if(PS[i]=='('){
                chk++;
            }
            else if (PS[i]==')'){
                chk--;
            }
        }
        if(chk==0){
            cout << "YES" << "\n";
        }
        else{
            cout << "NO" <<"\n";
        }
    }
    return 0;
}
cs



시간 제한메모리 제한제출정답맞은 사람정답 비율
2 초4 MB200973959840.597%

문제

N개의 풍선이 있다. 각 풍선 안에는 -N부터 N까지의 수가 적혀있는 종이가 들어 있다. 이 풍선들을 다음과 같은 규칙으로 터뜨린다.

우선, 제일 처음에는 1번 풍선을 터뜨린다. 다음에는 풍선 안에 있는 종이를 꺼내어 그 종이에 적혀있는 값만큼 이동하여 다음 풍선을 터뜨린다. 양수가 적혀 있을 경우에는 오른쪽으로, 음수가 적혀 있을 때는 왼쪽으로 이동한다. 풍선은 원형으로 놓여 있다고 생각한다. 즉, 1번 풍선의 왼쪽에 N번 풍선이 있고, N번 풍선의 오른쪽에 1번 풍선이 있는 것이다. 이동할 때에는 이미 터진 풍선은 빼고 생각한다.

예를 들어 다섯 개의 풍선 안에 차례로 3, 2, 1, -3, -1이 적혀 있었다고 하자. 이 경우 3이 적혀 있는 1번 풍선, -3이 적혀 있는 4번 풍선, -1이 적혀 있는 5번 풍선, 1이 적혀 있는 3번 풍선, 2가 적혀 있는 2번 풍선의 순서대로 터지게 된다.

입력

첫째 줄에 자연수 N(1≤N≤1,000)이 주어진다. 다음 줄에는 차례로 각 풍선 안의 종이에 적혀 있는 수가 주어진다. 편의상 0은 적혀있지 않다고 가정하자.

출력

첫째 줄에 터진 풍선의 번호를 차례로 나열한다.

예제 입력 1 

5
3 2 1 -3 -1

예제 출력 1 

1 4 5 3 2



<풀이과정> 


풍선에 적힌 쪽지가 음수인지 양수인지에 따라서 앞뒤로 push, pop 을 해줘야 하기 때문에 

기본적으로 deque자료형이 편리하지만 나는 그냥 vector자료형을 사용해서 풀었다. 

풍선의 번호와 숫자쪽지를 pair 배열로 생성. 

풍선이 터지면 배열에서 삭제하고 배열에 남아있는게 없을 때 까지 반복

종이에 적힌 숫자가 양수면 맨 앞의 요소를 맨뒤로 이동, 음수면 맨 뒤의 요소를 맨 앞으로 이동하는 방식으로 풍선의 이동을 구현.

이동의 횟수는 양수일 때는 종이에 적힌 숫자-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
#include<iostream>
#include<vector>
using namespace std;
int main(){
    int N;
    cin >> N; // 풍선의 개수
    vector<pair<int,int>> v; // N 개의 요소를 갖는 벡터를생성
    
    for(int i=1;i<=N;i++){ // 풍선 번호는 1부터 N까지  
        int num;
        cin >> num;
        
        v.push_back(make_pair(i,num));
//        v[i].first=i; v[i].second=num;// 다음과 같은 형태로 배열에 선언하면 코드가 작동되지 않는다!        
    }    
    while(v.empty()!=true){ //비어있지 않은 경우에 계속 반복 
        
        cout << v.front().first << " ";
        int a=v.front().second;
        v.erase(v.begin());
        
        
        if (a<0){ //음수 라면 - 맨 뒤를 맨 앞으로 
            for(int j=0;j<abs(a);j++){
                v.insert(v.begin(),v.back());
                v.erase(v.end());
            } 
        }
        else// 양수 라면- 맨 앞을 맨 뒤로 
            for(int j=0;j<a-1;j++){
                v.push_back(v.front());
                v.erase(v.begin());
            }
        }
    }
//        for(auto it=v.begin();it!=v.end();++it){
//            cout << (*it).second << "\n";
//        }
    return 0;
}
 
 
 
cs


시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초 (언어별 추가 시간 없음)128 MB128362890197624.991%

문제

한 줄로 된 간단한 에디터를 구현하려고 한다. 이 편집기는 영어 소문자만을 기록할 수 있는 편집기로, 최대 600,000글자까지 입력할 수 있다.

이 편집기에는 '커서'라는 것이 있는데, 커서는 문장의 맨 앞(첫 번째 문자의 왼쪽), 문장의 맨 뒤(마지막 문자의 오른쪽), 또는 문장 중간 임의의 곳(모든 연속된 두 문자 사이)에 위치할 수 있다. 즉 길이가 L인 문자열이 현재 편집기에 입력되어 있으면, 커서가 위치할 수 있는 곳은 L+1가지 경우가 있다.

이 편집기가 지원하는 명령어는 다음과 같다.

L커서를 왼쪽으로 한 칸 옮김 (커서가 문장의 맨 앞이면 무시됨)
D커서를 오른쪽으로 한 칸 옮김 (커서가 문장의 맨 뒤이면 무시됨)
B커서 왼쪽에 있는 문자를 삭제함 (커서가 문장의 맨 앞이면 무시됨)
삭제로 인해 커서는 한 칸 왼쪽으로 이동한 것처럼 나타나지만, 실제로 커서의 오른쪽에 있던 문자는 그대로임
P $$라는 문자를 커서 왼쪽에 추가함

초기에 편집기에 입력되어 있는 문자열이 주어지고, 그 이후 입력한 명령어가 차례로 주어졌을 때, 모든 명령어를 수행하고 난 후 편집기에 입력되어 있는 문자열을 구하는 프로그램을 작성하시오. 단, 명령어가 수행되기 전에 커서는 문장의 맨 뒤에 위치하고 있다고 한다.

입력

첫째 줄에는 초기에 편집기에 입력되어 있는 문자열이 주어진다. 이 문자열은 영어 소문자로만 이루어져 있으며, 길이는 100,000을 넘지 않는다. 둘째 줄에는 입력할 명령어의 개수를 나타내는 정수 N(1≤N≤500,000)이 주어진다. 셋째 줄부터 N개의 줄에 걸쳐 입력할 명령어가 순서대로 주어진다. 명령어는 위의 네 가지 중 하나의 형태로만 주어진다.

출력

첫째 줄에 모든 명령어를 수행하고 난 후 편집기에 입력되어 있는 문자열을 출력한다.

예제 입력 1 

abcd
3
P x
L
P y

예제 출력 1 

abcdyx

예제 입력 2 

abc
9
L
L
L
L
L
P x
L
B
P y

예제 출력 2 

yxabc

예제 입력 3 

dmih
11
B
B
P x
L
B
B
B
P y
D
D
P z

예제 출력 3 

yxz



<풀이과정> 


- 리스트를 이용한 풀이


초기 문자열을 입력받고 문자열을 리스트로 만들어서 풀이한다. 

문자열을 그대로 배열처럼 사용하게되면 삽입, 삭제 할 때 마다 모든 요소에 변화가 생겨 비효율적인 코드가 된다.


주의할 점은 'B' 삭제 명령어를 사용할 때 왼쪽 문자를 삭제하기 위해 커서를 왼쪽으로 이동하여 삭제한다. 

그러나 커서 오른쪽에 오는 문자는 그대로라고 했기 때문에 커서의 위치는 삭제 후에도 변함이 없어야 하기 때문에 

다시 오른쪽으로 이동하여 커서의 위치를 유지해준다. 



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
47
#include<iostream>
#include<string>
#include<list>
using namespace std;
 
int main(){
    int n; 
    string s; //초기 입력 문자열
 
    cin >> s; //abcd
    cin >> n;
    
    list<char> editor(s.begin(),s.end()); // 문자열을 리스트로  
    auto cursor=editor.end(); // 초기 커서의 위치는 문장의 맨 뒤
    
    while(n--){// 명령의 수 만큼 반복 
        char cmd;
        cin >> cmd; //명령어 입력 
        
        if(cmd=='L'){
            if(cursor!=editor.begin()){
                cursor--;
            }
        } 
        else if(cmd=='D'){
            if(cursor!=editor.end()){
                cursor++;
            }
        }
        else if(cmd=='B'){
            if(cursor!=editor.begin()){
                cursor--;
                editor.erase(cursor);
                cursor++;
            }
        }
        else if(cmd=='P'){
            char x;
            cin >> x;
            editor.insert(cursor,x);
        }    
    }
    for(auto &x:editor){
        cout << x;
    }
    return 0;     
}
cs


- 스택을 이용한 풀이 


커서를 기준으로 왼쪽과 오른쪽의 스택을 만든다. 

문제에서 필요한 작업은 왼쪽스택에서의 삽입과 삭제 - push, pop 명령으로 구현한다. 

커서의 오른쪽 이동은 왼쪽스택에 있는 요소를 오른쪽 스택에 옮기는 것으로,

왼쪽 이동은 오른쪽 스택에  있는 것을 왼쪽 스택에 옮기는 것으로 구현한다. 


마지막 출력을 위해서 오른쪽스택에 다 이동한 다음에 스택의 요소들을 하나씩 순서대로 출력한다. 


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include<iostream>
#include<string>
#include<stack>
using namespace std;
 
int main(){
    int n; 
    string s; //초기 입력 문자열
 
    cin >> s; //abcd
    cin >> n;
    stack<char> s1,s2;
    //stack<char> s1(s.begin(),s.end());
    for(auto &x:s){
        s1.push(x);
    }
    // s1.end() 커서의 위치  
    while(n--){// 명령의 수 만큼 반복 
        char cmd;
        cin >> cmd; //명령어 입력 
        
        if(cmd=='L'){
            if(!(s1.empty())){
                //s1에 든게 없다 == 커서가 가장 왼쪽이다  
                s2.push(s1.top());
                s1.pop(); 
            }
            
        } 
        else if(cmd=='D'){
            if(!s2.empty()){
                // s2에 든게 없다 == 커서가 가장 오른쪽이다  
                s1.push(s2.top());
                s2.pop();
            }
        }
        else if(cmd=='B'){
            if(!(s1.empty())){
                s1.pop();
            }
            
        }
        else if(cmd=='P'){
            char x;
            cin >> x;
            s1.push(x);
        }    
    }
    // 처음부터 순서대로 출력하기 위해 s1 스택에서 s2 스택으로 옮긴다. 
    while(!(s1.empty())){
        s2.push(s1.top());
        s1.pop();
    } 
    // s1에서 추가된 맨 위에서부터 출력하고 출력된 후에 스택에서 삭제  
    while(!(s2.empty())){
        cout << s2.top();
        s2.pop();
    }
    return 0;     
}
cs


시간 제한메모리 제한제출정답맞은 사람정답 비율
2 초256 MB103494540320944.594%

문제

숫자 카드는 정수 하나가 적혀져 있는 카드이다. 상근이는 숫자 카드 N개를 가지고 있다. 숫자 M개가 주어졌을 때, 이 숫자가 적혀있는 숫자 카드를 상근이가 가지고 있는지 아닌지를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N (1 ≤ N ≤ 500,000)이가 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 숫자가 주어진다. 숫자 카드에 적혀있는 숫자는 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다. 두 숫자 카드에 같은 숫자가 적혀있는 경우는 없다.

셋째 줄에는 M (1 ≤ M ≤ 500,000)이 주어진다. 넷째 줄에는 상근이가 가지고 있는 숫자 카드인지 아닌지를 구해야 할 M개의 숫자가 주어지며, 이 숫자는 공백으로 구분되어져 있다. 이숫자도 -10,000,000보다 크거나 같고, 10,000,000보다 작거나 같다

출력

첫째 줄에 입력으로 주어진 M개의 숫자에 대해서, 각 숫자가 적힌 숫자 카드를 상근이가 가지고 있으면 1을, 아니면 0을 공백으로 구분해 출력한다.

예제 입력 1 

5
6 3 2 10 -10
8
10 9 -5 2 3 4 5 -10

예제 출력 1 

1 0 0 1 1 0 0 1



<풀이과정>


고유한 숫자 M이 주어지기 때문에 먼저 상근이의 숫자 카드 집합을 만들고 

거기서 개수를 세어 1개가 있으면 1을 출력하고 없으면 0을 출력하면 된다. 

숫자에 따른 개수를 저장할 필요도 없기때문에 바로 출력해주면 된다. 



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
#include<iostream>
#include<set>
using namespace std;
 
int main(){
    int N; // 상근이가 가진 숫자카드의 개수
    cin >> N;
    set<int> s; // 상근이가 가진 카드 집합 
 
    while(N--){
        int x;
        cin >> x;// 카드에 적힌 숫자 
        s.insert(x);// 카드를 집합에 추가 
    } 
    
    int M; // 판별할 숫자의 개수
    cin >> M;
 
    for(auto i=0;i<M;i++){
        int x;
        cin >> x;// 판별할 숫자
 
        cout << s.count(x) << " ";
    } 
 
    return 0;     
}
cs


시간 제한메모리 제한제출정답맞은 사람정답 비율
2 초128 MB66252540179939.925%

문제

김진영이 듣도 못한 사람의 명단과, 보도 못한 사람의 명단이 주어질 때, 듣도 보도 못한 사람의 명단을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 듣도 못한 사람의 수 N, 보도 못한 사람의 수 M이 주어진다. 이어서 둘째 줄부터 N개의 줄에 걸쳐 듣도 못한 사람의 이름과, N+2째 줄부터 보도 못한 사람의 이름이 순서대로 주어진다. 이름은 띄어쓰기 없이 영어 소문자로만 이루어지며, 그 길이는 20 이하이다. N, M은 500,000 이하의 자연수이다.

출력

듣보잡의 수와 그 명단을 사전순으로 출력한다.

예제 입력 1 

3 4
ohhenrie
charlie
baesangwook
obama
baesangwook
ohhenrie
clinton

예제 출력 1 

2
baesangwook
ohhenrie



<풀이과정>


어렵지 않은 문제인데 생각지도 못한 곳에서 실수를 하는 바람에 의외로 고생을 좀 했다.

기본 아이디어는 듣지못한 사람들을 입력받아 배열로 만들고 보도 못한 사람들을 한명씩 입력하고 듣도못한 사람들 배열에서 있는지 확인하는 방식이다. 


여기서 빠르게 배열을 탐색하기 위해 이분탐색함수 binary_search를 사용했는데  이분탐색 알고리즘은 찾을 사전역할을 하는 것을 반드시 정렬된 상태로 만들어주고 해줘야 한다는 것을 잊었다!

중복되는 것을 찾았으면 새로운 배열에 넣고 정렬 한 후 출력해주면 된다. 



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
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
 
int main(){
    int N,M;
    cin >> N >> M;
    
    vector<string> v1(N);// 듣도못한 
     vector<string> l2;// 듣보잡  
    
    for(int i=0;i<N;i++){// 듣도못한 배열에 넣기 
        cin >> v1[i];
        //v1.push_back(a);
    } // 확인완료 잘들어갔음 
    sort(v1.begin(),v1.end()); //<-- 이분탐색은 반드시 정렬된 사전을 가지고 해야 의미가 있다.  
    string b;
 
    while(M--){// 보도못한 
        cin >> b;
        
        if(binary_search(v1.begin(),v1.end(),b)){
            l2.push_back(b);// 듣보잡에 넣는다
        }
    }
    sort(l2.begin(),l2.end());
    cout << l2.size() << "\n";
    
    for (auto x:l2){
        cout << x << "\n";
    }
 
    return 0;
}
 
cs




시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초256 MB69152551214937.199%

문제

네 자연수 A, B, C, D가 주어진다. 이 때, A와 B를 붙인 수와 C와 D를 붙인 수의 합을 구하는 프로그램을 작성하시오.

두 수 A와 B를 합치는 것은 A의 뒤에 B를 붙이는 것을 의미한다. 즉, 20과 30을 붙이면 2030이 된다.

입력

첫째 줄에 네 자연수 A, B, C, D가 주어진다. (1 ≤ A, B, C, D ≤ 1,000,000)

출력

A와 B를 붙인 수와 C와 D를 붙인 수의 합을 출력한다.

예제 입력 1 

10 20 30 40

예제 출력 1 

4060



< 풀이과정 > 


문제를 자세히 살피지 않으면 런타임에러가 날 수 있다. (나도 처음에 그랬다...)

문제의 조건을 자세히 보면 각 수는 1,000,000 까지 입력이 가능하다. 

ABCD모두 1,000,000이 입력된 경우에는 2,000,000 * 2,000,000 = 4,000,000,000,000 까지 최대값이 나올 수 있다. 

따라서 알맞은 자료형을 사용해 줘야 한다. 

문자열을 숫자형으로 바꾸는 함수는 

int 형  = stoi 

float형 = stof 

double형 = stod

long long형 = stoll

.

.

.

즉 자료형의 앞글자를 따서 뒤에 붙여주면 된다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <string>
using namespace std;
int main() {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
 
    string s1 = to_string(a) + to_string(b); //a+b결합
    string s2 = to_string(c) + to_string(d); //c+d결합
 
    long long n1 = stoll(s1);
    long long n2 = stoll(s2);
 
    cout << n1 + n2 << '\n';
    return 0;
}
cs



시간 제한메모리 제한제출정답맞은 사람정답 비율
1 초256 MB23930119241053451.652%

문제

알파벳 소문자와 대문자로만 이루어진 길이가 N인 단어가 주어진다.

한 줄에 10글자씩 끊어서 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 단어가 주어진다. 단어는 알파벳 소문자와 대문자로만 이루어져 있으며, 길이는 100을 넘지 않는다. 길이가 0인 단어는 주어지지 않는다.

출력

입력으로 주어진 단어를 열 개씩 끊어서 한 줄에 하나씩 출력한다. 단어의 길이가 10의 배수가 아닌 경우에는 마지막 줄에는 10개 미만의 글자만 출력할 수도 있다.

예제 입력 1 

BaekjoonOnlineJudge

예제 출력 1 

BaekjoonOn
lineJudge

예제 입력 2 

OneTwoThreeFourFiveSixSevenEightNineTen

예제 출력 2 

OneTwoThre
eFourFiveS
ixSevenEig
htNineTen



<풀이과정>


C++ 언어를 이용한 풀이


문자열 자료형과 getline함수를 사용해서 한 줄을 통째로 입력받는다. 

입력받은 글자 수만큼 반복하여 출력하면서 10으로 나눠 떨어질 때마다 줄바꿈을 하여 10개씩 출력되도록한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<iostream>
#include<string>
#include<vector>
using namespace std;
 
int main() {
    string s;
    getline(cin, s);
 
    for (int i = 0; i < s.size(); i++) {
        cout << s[i];
        if ((i+1) % 10 == 0) {
            cout << '\n';
        }
    }
    cout << '\n';
    return 0;
}
cs


C언어를 이용한 풀이 


%10s를 이용하여 문자열을 입력 받을 때 10개씩 끊어서 입력되도록 한다.

끊어서 입력받은 것을 출력.

더이상 출력할 입력 값이 없으면 루프는 종료된다.

  

1
2
3
4
5
6
7
8
9
10
#include<cstdio>
using namespace std;
 
int main(){
    char s[101]; 
    while(scanf("%10s",s)==1){
        printf("%s\n",s);
    }
    return 0;
}
cs



둘다 정답

C언어를 사용한 코드가 역시 더 효율적이다.



+ Recent posts