[Codeforces Round #666 (Div. 2)] B. Power Sequence 暴力枚举

题目链接:B. Power Sequence

题意

给你一个长度为n的序列a,让你通过一些操作使其变成一个叫“power sequence”的序列——存在一个c使得(0≤i≤n-1), a i = c i {a_i=c^i} ai=ci

  1. 你能够更改序列里每个元素的位置,这个操作不计入操作数内。
  2. 你可以选择任意一个元素增加或减少1,每进行一次这个操作,操作数+1。

问最少需要多少操作数使其变为“power squence”。

题解

本题我们先来分析, a i ≤ 1 e 9 , n ≤ 1 e 5 {a_i≤1e9,n≤1e5} ai1e9n1e5
那么我们能得出一个结论,操作数不可能超过 1 e 14 {1e14} 1e14,因为当 a i 全 为 1 e 9 {a_i全为1e9} ai1e9,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}} 1104,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}} 1103,106,109,1012

很容易我们发现当c>=1000时,n不能超过4。如果超过4,我们取c=1时就能得到答案。

所以这道题我们可以枚举c。由于 a i ≤ 1 e 9 , n ≥ 3 {a_i≤1e9,n≥3} ai1e9,n3,所以 c ≤ 1 e 9 {c≤\sqrt{1e9}} c1e9
在计算power sequence的 a i {a_i} ai时,如果 a i ≥ 1 e 14 {a_i≥1e14} ai1e14,就退出循环。

由于有剪枝,时间复杂度不会超。

代码

#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);
}

猜你喜欢

转载自blog.csdn.net/weixin_44235989/article/details/108320662