문제 링크


greedy 문제이다. 풀이는 간단하다. 괄호 개수의 제한이 없기 때문에 '-'를 만나면, 다음 '-'를 만날 때까지 그 값들을 전부 더한 뒤 계산 값에서 빼주면 된다.

왜냐하면 괄호 앞에 '-'가 있을 경우, 분배 법칙으로 괄호 안의 양수 값들은 전부 '-'로 처리되기 때문이다. 

나는 처음에 '-'를 토큰으로 문자열을 전부 나눈 뒤, 전부 덧셈 연산 처리를 한 다음에 빼줘서 풀었다.

하지만 그럴 필요 없이 그냥 값들을 전부 더해주다가 '-'를 만나면 그때부터 전부 다 빼주면 된다. 어차피 첫 '-'뒤의 '+'들은 전부 분배 법칙으로 '-'가 될 것이며, 다음 '-'를 만나면 그 전에 괄호를 닫고 다시 열게 되기 때문이다.


우선 처음에 그냥 '-'를 기준으로 토큰을 나눈 뒤 풀었던 코드이다. 나눈 토큰 들을 '+'처리한 다음에 첫 문자열을 제외한 나머지 문자열들은 전부 빼줬다.

//-가 나오면, 그 때부터 다음 -가 나올때까지 전부다 괄호를 쳐버리면 된다.
//-를 토큰으로 문자열을 추출한다. 그 문자열 안에 있는 값들의 +연산을 모두 처리하면 된다. 
#include <cstdio>
#include <cstring>
#include <cstdlib>
char cal[51] = { 0, };
char ca[51][51] = {0,};
char* ptr;
int ret,i=0;
//+연산을 처리하는 함수 
int calculate(char* str) {
    int r = 0;
    char* ptr2;
    ptr2 = strtok(str, "+");
    r += atoi(ptr2);
    while (ptr2 = strtok(NULL, "+")) {
        r += atoi(ptr2);
    }
    return r;
}
int main() {
    scanf("%s", cal);
    //-를 토큰으로 분해하고, 각 문자열을 저장한다. 
    ptr = strtok(cal, "-");
    strcpy(ca[i++],ptr);
    while (ptr = strtok(NULL, "-")) {
        strcpy(ca[i++],ptr);
    }
    //분해한 문자열을 전부 +연산 처리를 하고, 첫 수를 제외한 나머지 수는 전부 뺄셈 처리를 한다. 
    ret=calculate(ca[0]);
    for(int j=1;j<i;j++){
        ret -= calculate(ca[j]);
    }
    printf("%d",ret);
}


이 코드만 봐도 알고 보면 첫 '-'이후의 값들은 전부 다 빼주면 된다는 걸 알 수 있다.

다음 코드는 이를 적용해 보았다.


#include <cstdio>
#include <cstring>
#include <cstdlib>
char cal[51] = { 0, };
char ca[51] = {0,};
char* ptr;
int ret,i=0;
//덧셈을 처리하는 함수. 전과 달라진건 -,+을 안가리고 전부 더해버린다. 
int calculate(char* str) {
    int r = 0;
    char* ptr2;
    ptr2 = strtok(str, "+-");
    r += atoi(ptr2);
    while (ptr2 = strtok(NULL, "+-")) {
        r += atoi(ptr2);
    }
    return r;
}
int main() {
    scanf("%s", cal);
    //첫 -를 기준으로 토큰을 나눈다. 
    ptr = strtok(cal, "-");
    strcpy(ca,ptr);
    //첫 - 이후의 문자열을 받는다. 
    ptr = strtok(NULL,"");  
    ret=calculate(ca);
    //첫 - 이후의 문자열은 전부 덧셈 처리한 뒤 빼준다. 
    if(ptr!=NULL)ret-=calculate(ptr); 
    printf("%d",ret);
}

마지막으로는 다른 분 코드를 참조해 짜본, 라이브러리 함수를 쓰지 않고 배열을 하나하나 검사해서 짜는 코드이다.


#include <cstdio> char cal[51] = { 0, }; int ret=0,n=0,i=0,flag=0; int main() { scanf("%s", cal); while(cal[i] != 0){ //숫자이면 if(cal[i] >='0' && cal[i]<='9'){ //이전에 저장한 숫자의 자릿수를 하나 늘려주고 이 값을 더해준다. n*=10; n+=cal[i]-'0'; } //그 후 지금까지 숫자값들을 0으로 초기화해준다. else{ //-연산자를 만난적이 없으면, 즉 flag가 0이면 그냥 더해준다. if(flag==0) ret +=n; //-연산자를 만난적이 있으면, 즉 flag가 1이면 뺄셈처리한다. else ret-=n; //첫 -이면, 즉 -이고 flag가 0이면 flag를 1로 만들어준다. if(cal[i]=='-'&&flag==0) flag=1; n = 0; } i++; } //마지막 숫자를 flag에 맞게 처리해준다. if(flag==0) ret+=n; else if(flag==1) ret-=n; printf("%d",ret); }


'Algorithm > Problems' 카테고리의 다른 글

알고스팟 - NQUEEN, 백준 - 9663 N-QUEEN  (1) 2016.02.25
알고스팟 - MORSE, DICT  (0) 2016.02.25
백준 - 1963 소수경로  (0) 2016.02.24
백준 - 2960 에라토스테네스의 체  (1) 2016.02.24
백준 - 1946 신입사원  (0) 2016.02.23

+ Recent posts