G - Eva’s Balance (3進制&數論)
題意:給個的冪次方數:和一個數,要求用這個數中若干個使左右兩個秤盤數之和相等.
(開始被放在左盤)
思路:因爲都是的冪次方,題目等價於構造兩個的冪次方之和相減等於,所以考慮進制下來表示.
所以被轉化爲的數字串。當該位爲時,顯然可以不會用到或者直接抵消掉。
當時,因爲。所以等價於然後。
當時,顯然,所以等價於.然後再根據的正負情況,將負的給左盤,正的給右盤,此題就解決了。
時間複雜度:
AC代碼:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int N=2e3+5,inf=0x3f3f3f3f;
int a[N],n,t;
#define mst(a) memset(a,0,sizeof a)
int ksm(int a,int n){ //快速冪板子.
int ans=1;
while(n){
if(n&1) ans=ans*a;
a=a*a;
n>>=1;
}
return ans;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
mst(a);
int k=0;
while(n){ //轉換爲三進制.
a[++k]=n%3;
n/=3;
}
int f1=0,f2=0;//用來控制格式(逗號)
for(int i=1;i<=k+1;i++){ //重點轉換.
if(a[i]==2) a[i]=-1,a[i+1]++;
else if(a[i]==3) a[i]=0,a[i+1]++;
}
for(int i=1;i<=k+1;i++){ //輸出 注意是可能k+1位.
if(a[i]==-1){
if(f1) printf(",%d",ksm(3,i-1));
else f1=1,printf("%d",ksm(3,i-1));
}
}
if(!f1) printf("empty");
printf(" ");
for(int i=1;i<=k+1;i++){
if(a[i]==1){
if(f2) printf(",%d",ksm(3,i-1));
else f2=1,printf("%d",ksm(3,i-1));
}
}
if(!f2) printf(" empty");
puts("");
}
return 0;
}