题目链接:B. Power Sequence
题意
给你一个长度为n的序列a,让你通过一些操作使其变成一个叫“power sequence”的序列——存在一个c使得(0≤i≤n-1), a i = c i {a_i=c^i} ai=ci。
- 你能够更改序列里每个元素的位置,这个操作不计入操作数内。
- 你可以选择任意一个元素增加或减少1,每进行一次这个操作,操作数+1。
问最少需要多少操作数使其变为“power squence”。
题解
本题我们先来分析,
a
i
≤
1
e
9
,
n
≤
1
e
5
{a_i≤1e9,n≤1e5}
ai≤1e9,n≤1e5。
那么我们能得出一个结论,操作数不可能超过
1
e
14
{1e14}
1e14,因为当
a
i
全
为
1
e
9
{a_i全为1e9}
ai全为1e9,n为
1
e
5
{1e5}
1e5时,我们取c=1就能得到最小值。
然后我们继续分析
当c=
1
0
4
{10^4}
104时,那么power sequence序列为
1
,
1
0
4
,
1
0
8
,
1
0
12
{1,10^4,10^8,10^{12}}
1,104,108,1012
当c=
1
0
3
{10^3}
103时,那么power sequence序列为
1
,
1
0
3
,
1
0
6
,
1
0
9
,
1
0
12
{1,10^3,10^6,10^{9},10^{12}}
1,103,106,109,1012
很容易我们发现当c>=1000时,n不能超过4。如果超过4,我们取c=1时就能得到答案。
所以这道题我们可以枚举c。由于
a
i
≤
1
e
9
,
n
≥
3
{a_i≤1e9,n≥3}
ai≤1e9,n≥3,所以
c
≤
1
e
9
{c≤\sqrt{1e9}}
c≤1e9。
在计算power sequence的
a
i
{a_i}
ai时,如果
a
i
≥
1
e
14
{a_i≥1e14}
ai≥1e14,就退出循环。
由于有剪枝,时间复杂度不会超。
代码
#include<iostream>
#include <sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
//typedef int fuck;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
//#define int long long
const double PI=acos(-1.0);
const double eps=1e-6;
//const ll mod=1e9+7;
const ll inf=1e18;
const int maxn=1e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll a[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lld",&a[i]);
sort(a,a+n);
ll ans=inf;
for(ll c=1;c<=sqrt(1e9)+1;c++)
{
ll tmp=0,tt=1;
int flag=1;
for(int i=0;i<n;i++)
{
if(tt>=1e14) { flag=0;break;}
tmp+=abs(a[i]-tt);
tt*=c;
}
if(flag) ans=min(ans,tmp);
}
printf("%lld\n",ans);
}