개요
문제가 있는 링크
플레이 5, 정수론, 역추적
정육면체 세 개로 나눴을 때 N이 꼬리인 수 찾기
입장
- 역추적 대신 bigInt를 구현할 수 있는지 여부에 대한 질문은 단순히 역추적 자체입니다. 문자열을 거꾸로 삽입한 후 앞에서 0부터 9까지 삽입하고 다음 단계에서 큐브의 하위 문자열이 같은지 확인합니다.할 수 있어요.
- BigInt를 사용해야 합니까? 그렇다면 주사위에서 10자리를 굴리면 30자리가 되어 롱롱의 범위를 넘어선다. 문자열로 취급하고 10자리에서 자릅니다. 다른 방법으로 구현하신 분들도 계시는데 저는 해결 방법도 몰랐습니다.
- 만약에 곱한 값의 n번째 자리와 목표값이 같으면 건너뛴다. 오류를 줄이려면 n번째 숫자가 0이면 곱한 값이 아직 채워지지 않은 것입니다.해야한다.
- 즉, 예를 들어 27을 입력하면 009가 됩니다. 이렇게 하면 결과 값에 0이 붙는 경우가 있으니 잘 제거해 주세요.
의사 코드
struct BigInt {
// 뒤집은 상태로 입력
string v
int length
} n, t
// pos = 현재 위치, action = 어떤 숫자를 추가했는지
recur(t, pos, action) {
if (pos = end)
// 0빼고 뒤집어 출력
print(reverse(action))
if (t(pos) = n(pos))
return recur(t, pos+1, action+"0")
if (!t(pos) && n(pos)=='0')
return recur(t, pos+1, action+"0")
for (i = '0'~'9')
// action에 i추가, 길이는 현재 위치+1
BigInt a = {action+i,pos+1}
BigInt b = a*a*a
if (b(pos) = n(pos))
if (recur(b, pos+1, action+i))
return 1;
return 0;
}
소스 코드
#include <iostream>
#include <algorithm>
using namespace std;
#define all(v) v.begin(),v.end()
#define ist istream&
typedef string str;
struct big {
str v;
int n;
} n;
ist operator >> (ist in, big &b) {
in >> b.v;
reverse(all(b.v));
b.n = b.v.size();
return in;
}
big operator * (big a, big b) {
int p,k,m;
m = a.n+b.n+1;
str c(m, 0);
for (int i=0; i<a.n; i++) {
int d = 0;
for (int j=0; j<b.n; j++) {
k = i+j;
p = (a.v(i)-'0')*(b.v(j)-'0')+d+c(k);
d = p / 10;
c(k) = p % 10;
}
if (d) c(i+b.n) += d;
}
while (!c(m-1)&& m>1) m--;
c = c.substr(0,20);
for (auto &x:c) x+='0';
return {c.substr(0,m), m};
}
bool rec(big v, int c, str r) {
if (c==n.n) {
while (r.back()=='0')
r.pop_back();
reverse(all(r));
cout << r << "\n";
return 1;
}
if (v.v(c)==n.v(c))
return rec(v,c+1,r+'0');
if (!v.v(c)&&n.v(c)=='0')
return rec(v,c+1,r+'0');
for (char i='0'; i<='9'; i++) {
big a = {r+i,c+1};
big b = a*a*a;
if (b.v(c)==n.v(c))
if (rec(b,c+1,r+i))
return 1;
}
return 0;
}
void test() {
cin >> n;
rec({"",0},0,"");
}
int main() {
int t;
cin>>t;
while(t--) test();
}

