728x90
중복순열로 모든 가능성을 탐색해야한다. 물론 1 2 3 같은 연산은 아에 안하는게 좋지만 그건 너무 어렵고 완전 탐색해도 시간이 오래 걸리지않는다. Time complex 가 O(3^9) 이기 때문에 시간은 널럴하다.
백트래킹 완전탐색으로 중복순열개의 코드들을 검사하면 된다. 조금 어려웠던 건 문자열로 수식을 받아서 처리하는 일이었다.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
string opbox = "";
char op[3] = { '+', '-', ' ' };
int opSize;
int N;
int cnt = 1;
vector<string> answer;
bool check(string str) {
for (int i = 0; i < str.size(); i++) {
if (str[i] == ' ')
str.erase(str.begin() + i);
}
char op = '-1';
int tmp = 0;
int result = 0;
for (int i = 0; i < str.size(); i++) {
if (str[i] == '+') { // 연산자이면
op = '+';
}
else if (str[i] == '-') {
op = '-';
}
else { // 연산자가 아님
tmp = (str[i] - '0');
int t = i + 1;
for (int j = t; j < str.size(); j++) {
if (str[j] != '+' && str[j] != '-') {
tmp = tmp * 10 + (str[j] - '0');
i++;
}
else {
break;
}
}
if (op == '+')
result += tmp;
else if (op == '-')
result -= tmp;
else
result += tmp;
}
}
return result == 0;
}
void dfs() {
if (opbox.size() == opSize) {
int opindex = 0;
string checkstring = "";
//cout << cnt << " ";
for (int i = 0; i < N; i++) {
checkstring.push_back(i + 1 + '0');
if (i != N - 1)
checkstring.push_back(opbox[i]);
}
if (check(checkstring))
answer.push_back(checkstring);
return;
}
for (int i = 0; i < 3; i++) {
opbox.push_back(op[i]);
dfs();
opbox.pop_back();
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int M;
cin >> M;
for (int i = 0; i < M; i++) {
cin >> N;
opSize = N - 1;
dfs();
sort(answer.begin(), answer.end());
for (string a : answer) cout << a << '\n';
cout << '\n';
opbox.clear();
answer.clear();
}
}
'백준 문제 풀이' 카테고리의 다른 글
백준 14699번 관악산 등산(C++) (1) | 2023.05.08 |
---|---|
백준 12869번 뮤탈리스크(C++) (1) | 2023.05.07 |
백준 14500번 테트로미노 (C++) (0) | 2023.03.06 |
백준 15661번 링크와 스타트(C++) (0) | 2023.03.06 |
백준 14889번 스타트와 링크(C++) (0) | 2023.03.06 |