괄호

문제번호 : 9012 번

문제링크 : https://www.acmicpc.net/problem/9012

문제

괄호 문자열(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”를 한 줄에 하나씩 차례대로 출력해야 한다.

예제

입력

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

출력

NO
NO
YES
NO
YES
NO

풀이

)괄호가 (괄호를 만나면 스택에서 pop되는 방식으로, 마지막괄호까지 검사하여 스택에 남은 괄호가 있으면 NO 없으면 YES를 출력하도록 하였다.

  1. 괄호를 입력받아서 str변수에 저장시킴

  2. str의 길이만큼 for문을 돌려서 괄호 하나씩 검사

    1. ')' 일 경우 스택에 있는 '('를 pop함 만약 첫번째, 스택이 비었을때 ')'입력이 되면 반복문을 빠져나와 바로 NO를 출력하도록 하였다.

    2. '(' 일 경우 스택에 push

  3. 반복문을 빠져나와서 스택에 남은 괄호가 없으면 YES, 있으면 NO를 출력하고 스택을 비워준다


코드

#include<iostream>
#include<string>
#include<stack>
#define IOFAST() ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;

int main(){
IOFAST();

int t, j;
string str;
stack<char> st;
cin >> t;

for (int i = 0; i < t; i++){
str = "";
cin >> str;
for (j = 0; j<str.length(); j++){
if (str[j] == ')'){
if (st.empty()) {// ) 가 맨처음 들어온경우(예외처리)
st.push(str[j]);
break;
}
st.pop(); //(를 빼냄
}
else{
st.push(str[j]);
}
} //for
if (st.empty() ){
cout << "YES\n";
}
else{
cout << "NO\n";
while (!st.empty()) st.pop();
}

}

return 0;
}

'Algorithm > 백준 BOJ' 카테고리의 다른 글

[2156] 포도주 시식  (0) 2018.05.23
[2579] 계단오르기  (0) 2018.05.23
[1260] DFS와 BFS  (0) 2018.05.11
[1966]프린터 큐  (0) 2018.05.11
[1924] 2007년  (0) 2018.04.30

2007년

문제번호 : 1924 번

문제링크 : https://www.acmicpc.net/problem/1924


문제

오늘은 2007년 1월 1일 월요일이다. 그렇다면 2007년 x월 y일은 무슨 요일일까? 이를 알아내는 프로그램을 작성하시오.

입력

첫째 줄에 빈 칸을 사이에 두고 x(1≤x≤12)와 y(1≤y≤31)이 주어진다. 참고로 2007년에는 1, 3, 5, 7, 8, 10, 12월은 31일까지, 4, 6, 9, 11월은 30일까지, 2월은 28일까지 있다.

출력

첫째 줄에 x월 y일이 무슨 요일인지에 따라 SUN, MON, TUE, WED, THU, FRI, SAT중 하나를 출력한다.

예제

입력

1 1

출력

MON

풀이

  1. week[]에는 출력될 값을 담아놓고, day[]에는 각 달의 일 수를 초기값으로 넣어준다.

  2. 월과 일을 입력받아 반복문으로 x-1월까지의 총 일수를 num이라는 변수에 더해준다.

  3. x월의 일 수인 y를 num에 더해준 후 그것을 7으로 나눈 결과값을 result변수에 넣어준다

  4. week의 인덱스값result을 출력해 주면 끝

코드

#include<iostream>
#include <string>

using namespace std;
int main(){

string week[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };//0,1,2,3,4,5,6
int day[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int x, y, result,num=0;

cin >> x >> y;
for (int i = 1; i<x; i++){
num +=day[i];
}
result = (num+y) % 7;

cout << week[result] << '\n';
}

'Algorithm > 백준 BOJ' 카테고리의 다른 글

[2156] 포도주 시식  (0) 2018.05.23
[2579] 계단오르기  (0) 2018.05.23
[1260] DFS와 BFS  (0) 2018.05.11
[1966]프린터 큐  (0) 2018.05.11
[9012] 괄호  (0) 2018.05.01

C++ 입출력 속도 차이

언어입력방식수행시간(초)
C/C++scanf0.798
C/C++getchar(*)0.390
C++std::cin2.051
C++std::ios::sync_with_stdio(false) + std::cin0.796
javajava.util.Scanner6.068
javajava.io.BufferedReader(*)0.934
golangfmt.Scan44.557
golangbufio.Reader + fmt.Fscan9.899
golangbufio.Scanner(*)1.299

(*): 문자(열) -> 정수 변환 필요


cin,cout 보다 scanf,printf 가 컴파일속도가 훨씬 빠르기 때문에 scanf, printf를 쓰는 것을 권장하지만 cin, cout 을 굳이 쓰고 싶다면 코드에서 ios::sync_with_stdio(false) 를 선언해주면 속도가 얼추 비슷해지는 것을 알 수 있다.

cin, cout 의 성능을 높히는 방법을 소개하겠다.

1. ios::sync_with_stdio(false)

ios::sync_with_stdio cpp의 iostream을 c의 stdio와 동기화시켜주는 역할을 합니다. 이는 iostream, stdio의 버퍼를 모두 사용하기 때문에 딜레이가 발생하게 됩니다. ios::sync_with_stdio(false)는 이 동기화 부분을 끊는 함수입니다. 이를 사용하면 c++만의 독립적인 버퍼를 생성하게 되고 c의 버퍼들과는 병행하여 사용할 수 없게 됩니다. 대신 사용하는 버퍼의 수가 줄어들었기 때문에 속도는 높아지게 됩니다.

2.cin.tie(NULL);cout.tie(NULL);

디폴트는 cout,cin이 tie되어 있습니다.이것을 풀어줍니다.

3.std::endl 대신에 "\n" 사용하기

endl는 개행만 해주는 것이아니라 개행 + 출력버퍼를 비워야 하기때문에 느립니다.


'C++' 카테고리의 다른 글

C++ 인라인 함수  (0) 2018.05.02
C++, C와 무엇이 다를까  (0) 2018.04.30

C++ , C와 무엇이 다를까


c++11의 새로운 자료형

자료형설명
long long64비트 정수 (컴파일러에 따라 약간 다를 수 있음)
char16_t16비트 문자(유니코드 처리를 위한 자료형)
char32_t32비트 문자(유니코드 처리를 위한 자료형)
auto컴파일러가 자동으로 형식을 규정하는 자료형(ex. auto a =10;)
decltype(expr)expr과 동일한 자료형(ex. int x=10;deltype(x) y =20;)

auto 자료형

초깃값의 형식에 맞춰 선언하는 인스턴스의 형식이 자동으로 결정된다.

메모리 동적 할당

malloc(), free() 함수를 대신할 new, delete 연산자 !

new, delete 연산자 내부에서 malloc(), free()함수를 호출한다.그리고 단순히 메모리를 과니하는 이상의 일들을 수행한다.

new 연산자는 malloc()함수와 다르게 "메모리 크기를 정하지 않는다."

형식 *변수이름 = new 형식;

delete 변수이름;

형식 *변수이름 = new 형식[요소개수];

delete[] 변수이름;

참조자 형식

참조자(reference)형식은 C에는 없는 형식으로 포인터와 구조적으로 비슷하다. 그러나 겉으로 드러나는 모습은 전혀 다르다. 그리고 참조자형식은 반드시 초기화해야한다. 또 참조자는 처음 어떤 변수와 짝을 이루게 되면 짝이 달라지지 않는다.

형식 &이름 = 원본;

ex) int &ref = nData ;

참조자 예제

#include "stdafx.h"
#include <iostream>
using namespace std;
void Swap(int &a, int &b){ //매개변수의 형식이 참조형식 !!
int nTemp = a;
a = b;
b = nTemp;
}
int _tmain(int argc, _TCHAR* argv[])

{
int x = 10, y = 20;
Swap(x, y);
cout << "x : " << x << endl;
cout << "y : " << y << endl;
}

범위 기반 for문

반복 횟수는 배열 요소 개수에 맞춰 자동으로 결정

for(auto 요소변수 : 배열명)

{ 반복구문 ...; }

ex) for(auto n : arr){ ...}

하지만 배열의 값을 변경시키기위해서는

for(auto &n : arr)

와 같이 참조자를 요소형식으로 선언하여야한다.

//////잘못된 소스 
#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int arr[5] = { 10, 20, 30, 40, 50 };

for (auto a : arr){ //값 선언으로는 배열의 원소값을 변경시킬 수없다.
a = a+10;
}
for (auto a : arr){
cout << a << ' ';
}

}

//결과값: 10 20 30 40 50

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
int arr[5] = { 10, 20, 30, 40, 50 };

for (auto &a : arr){
a = a+10;
}
for (auto a : arr){
cout << a << ' ';
}

}

//결과값 : 20 30 40 50 60

'C++' 카테고리의 다른 글

C++ 인라인 함수  (0) 2018.05.02
C++입출력 속도, 성능 개선  (0) 2018.04.30

스택

  • 스택은 LIFO(Last In First Out)원리로 동작하는 선형적인 자료구조

  • 데이터가 들어오고 나가는 입구가 하나뿐이므로 입구로 들어간 데이터가 스택에 차곡차곡 쌓여있다가 들어간 반대순서로 나온다.


스택을 c로 구현하는 방법도 있지만 C++에서 제공하는STL을 통해 쉽게 사용 할 수 있다.

먼저 <stack> 라이브러리를 선언한 후에 stack<int> 로 stack 컨데이너 객체를 생성 하면 아래와 같은 함수들을 사용할 수 있다.

  • st.push(x) : 스택에 데이터 x를 입력한다.

  • st.pop() : 스택의 데이터를 삭제한다.

  • st.top() : 스택의 가장 꼭대기의 데이터를 반환한다.

  • st.empty() : 스택이 비어있는지 판단한다.

예제

#include<iostream>

#include<stack> //stack 라이브러리 불러옴 

using namespace std;


int main(){


stack<int> st; //스택 선언


st.push(10); //스택에 삽입

st.push(20);

st.push(100);


while (1){


if (st.empty()){   // 스택이 비었는지 확인

cout << "stack에 데이터 없음" << endl;

break;

}


cout << st.top() << endl; //데이터 반환

st.pop(); //데이터 삭제


}


return 0;


'C++ > STL' 카테고리의 다른 글

C++ STL Queue 큐 사용법과 예제  (0) 2018.05.03

+ Recent posts