https://www.acmicpc.net/problem/14395
14395번: 4연산
첫째 줄에 정수 s를 t로 바꾸는 방법을 출력한다. s와 t가 같은 경우에는 0을, 바꿀 수 없는 경우에는 -1을 출력한다. 가능한 방법이 여러 가지라면, 사전 순으로 앞서는 것을 출력한다. 연산의 아
www.acmicpc.net
[난이도] Gold5
[유형] BFS
[풀이]
*,+,-,/를 모두 사용하면서 연산을 진행하면 굉장히 많은 경우의 수가 나올 것 같지만
생각해보면 '-'는 사용할 일이 없습니다. '-' 연산을 사용하면 무조건 0이 되는데
결과값인 t이 1 이상이기 때문에 어떤 입력에도 0을 만들 일이 없습니다.
'/'의 사용시 무조건 1을 만들기 때문에 최초 1회에만 사용하는 것이 의미가 있습니다.
결국 시작 숫자 s에서 *,+를 이용해 t를 만드는 경우와, 처음에 '/' 연산을 사용해
1을 만든 뒤 *,+를 이용해 t를 만드는 경우 둘 중 최적의 경우를 찾으면 됩니다.
수의 범위가 10^9이므로 많은 수가 등장할 것 같지만 +,* 연산을 이용할 경우 수가 큰 폭으로 증가하므로
10^9에 도달할 때까지 10^9만큼 많은 수가 등장하지는 않을 것입니다.
이를 이용해 set으로 visit한 숫자에 체크를 해주는 BFS를 사용할 수 있습니다.
s부터 시작해 t를 만든 경우, '/' 연산을 사용해 1부터 시작해 t를 만든 두 경우를 비교해서
최적의 답을 구해주면 됩니다.
#include <cstdio>
#include <string>
#include <set>
#include <iostream>
#include <queue>
using namespace std;
using ll = long long;
ll s,t;
string sol(ll sv,string sstr){
queue<pair<ll,string>> q;
q.push({sv,sstr});
set<ll> visit;
visit.insert(sv);
while(!q.empty()){
auto [v,str] = q.front();
q.pop();
if(v==t) return str;
if(v*v<=t && visit.find(v*v)==visit.end()) {
visit.insert(v*v);
q.push({v*v,str+"*"});
}
if(v+v<=t && visit.find(v+v)==visit.end()) {
visit.insert(v+v);
q.push({v+v,str+"+"});
}
}
return "0";
}
int main(){
cin >> s >> t;
if(s==t) {
cout << 0;
return 0;
}
string ans1 = sol(s,"");
string ans2 = sol(1,"/");
if(ans1=="0" && ans2=="0") cout << -1;
else if(ans1=="0") cout << ans2;
else if(ans2=="0") cout << ans1;
else {
if(ans1.size()<ans2.size()) cout << ans1;
else if(ans1.size()>ans2.size()) cout << ans2;
else{
if(ans1<ans2) cout << ans1;
else cout << ans2;
}
}
}
https://github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold5/14395.cpp
'Problem-Solving > BOJ' 카테고리의 다른 글
[BOJ/백준][Gold5] 2671 : 잠수함식별 (C++) (0) | 2022.01.23 |
---|---|
[BOJ/백준][Gold5] 15591 : MooTube (Silver) (C++) (0) | 2022.01.23 |
[BOJ/백준][Gold5] 14728 : 락치기 (C++) (0) | 2022.01.23 |
[BOJ/백준][Gold5] 2591 : 숫자카드 (C++) (0) | 2022.01.23 |
[BOJ/백준][Gold5] 1041 : 주사위 (C++) (0) | 2022.01.23 |