P5623 [Celeste-A] Sever the Skyline 题解
AnteAntibe · · 题解
P5623 [Celeste-A] Sever the Skyline
随机挑题,写掉之后发现竟然没有题解!于是前来水咕值。
Description
题意大概是这样:给出三个数
Solution
首先观察一组合法的构造需要满足什么性质。
核心的约束显然是“不能有倍数关系”这一条。用
所以如何避免这件事情呢?思考一个直观的做法!我们让
乍一看很像数学题啊!但是稍微思考一下就发现:同时具有幂、加法、乘法操作,很难找到数字之间的关系。无迹可寻的时候就考虑暴力吧!
假定
由于每次除以了
写一个搜索,在最后
注意:
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll p ,q ,n ,maxx ,thi;
inline ll ksm(ll base ,ll p) {
ll res = 1;
for(;p>0;) {
if(p % 2) {
res *= base;
res = res;
}
p >>= 1;
base = base * base;
}
return res;
}
ll ans[N] ,flag;
inline void dfs(ll res ,ll la ,ll num ,ll iidx) { //num 需要 乘回来的数
if (flag) {
return;
}
if (res == 0) {
for (register int i=iidx-1 ;i>=1 ;i--) {
if (i != 1) {
printf("%lld " ,ans[i]);
}
else {
printf("%lld" ,ans[i]);
}
}
flag = 1;
return;
}
if (res%p == 0) {
ans[iidx] *= p;
dfs(res/p ,la ,num*p ,iidx);
}
for (register int i=la ;i>=0 ;i--) {
thi = ksm(q ,i);
if ((res - thi) % p == 0) {
if (res < thi) {
continue;
}
ans[iidx] = num * thi;
dfs((res - thi)/p ,i-1 ,num*p ,iidx+1);
ans[iidx] = 0;
}
}
}
int main() {
int T;
scanf("%d" ,&T);
for (;T--;) {
scanf("%lld %lld %lld" ,&n ,&p ,&q);
if (p < q) {
swap(p ,q);
}
// init
ll tmp = n;
maxx = 0;
thi = 1;
flag = 0;
for (register int i=1 ;i<=n ;i++) {
if (tmp) {
tmp /= q;
maxx += 1;
thi *= q;
}
else {
break;
}
}
dfs(n ,maxx+2 ,1 ,1);
printf("\n");
}
return 0;
}