알고리즘
[C/C++] 코드업(codeup) 3540번 0 만들기 게임
SWBlossom
2020. 2. 1. 22:00
▽문제 바로가기
https://codeup.kr/problem.php?id=3540
0 만들기 게임
1+2-3+4-5-6+7 1+2-3-4+5+6-7 1-2 3+4+5+6+7 1-2 3-4 5+6 7 1-2+3+4-5+6-7 1-2-3-4-5+6+7
codeup.kr
입력
정수 N이 입력된다.( 3 <= N <= 9 )
출력
0으로 만드는 모든 수식을 출력한다.
출력 순서는 공백, +, - 순서로 출력한다.
문제 풀이
완전 탐색 후 합이 0이 되는 모든 수식을 출력해야 합니다.
합이 0이 되는지 계산하는 과정이 조금 복잡했습니다. 출력도 해야 하고 계산도 해야 하니...
숫자 외 빈칸, +, - 가 있습니다. 그러나 실질적으로 계산이 이루어지는 연산은 + 와 - 이니 빈칸과 구분해줍니다.
+와 -를 만나면 다음 숫자와 연산을 합니다.
다음 숫자는 숫자 다음 공백이 없을 때까지 계산해 줍니다.
예를 들어 1 뒤에 공백이 있다면 1에 10을 곱하고 2를 더해서 12를 만듭니다. 또 공백이 있다면 12에 10을 곱해서 3을 더해서 123을 만듭니다.
#include <stdio.h>
using namespace std;
int n; //입력받을 정수n
char arr[20]; //출력용 배열
//계산을 위한 숫자
int nextNum(int i){
int num = i;
while(arr[(i*2)-1]==' '){
num = num*10 + i + 1;
i++;
}
return num;
}
//합이 0인지 판별
bool isZero(){
int sum = nextNum(1); //초기값
for(int i=1;i<=n*2-2;i++){
//실질적인 계산이 일어나는 연산
if(arr[(i*2)-1]=='+') sum += nextNum(i+1);
else if(arr[(i*2)-1]=='-') sum -= nextNum(i+1);
}
if(sum==0) return true;
else return false;
}
//백트래킹
void backtracking(int i){
//완전탐색 끝
if(i==n){
//합이 0이면 출력
if(isZero()){
for(int i=0;i<=n*2-2;i++){
printf("%c", arr[i]);
}
printf("\n");
}
return;
}
//출력 순서는 공백, +, - 순이므로 탐색을 이 순서로
arr[(i*2)-1] = ' ';
backtracking(i+1);
arr[(i*2)-1] = '+';
backtracking(i+1);
arr[(i*2)-1] = '-';
backtracking(i+1);
}
int main(){
scanf("%d", &n);
//'1', ' ', '2', ' ', ... 으로 초기화
int one = 49; //숫자49는 아스키코드 '1'
for(int i=0;i<n*2;){
arr[i] = one;
one++;
i+=2;
}
//백트래킹
backtracking(1);
return 0;
}