[Codeforces Round#666(Div。2)] B.パワーシーケンスのブルートフォース列挙

トピックリンク:B.電源シーケンス

題名

シーケンスaに長さnを与え、それをいくつかの操作によって「パワーシーケンス」と呼ばれるシーケンスにしましょう。(0≤i≤n-1)、ai = ci {a_i = cのようなcがあります。 ^ i}a=c

  1. シーケンス内の各要素の位置を変更できますが、この演算はオペランドではカウントされません。
  2. 1ずつ増減する要素を選択できます。この演算が実行されるたびに、オペランドは+1になります。

「パワーシーケンス」にするために必要なオペランドの最小数を尋ねます。

回答

最初にこの質問を分析しましょう。ai≤1 e 9、n≤1 e 5 {a_i≤1e9、n≤1e5}a1 e 9 n1 e 5
次に、オペランドが1 e 14 {1e14}を超えることはできないという結論を導き出すことができます1 e 1 4、なぜならaiがすべて1 e 9のとき{a_iはすべて1e9}だからaすべてがある1 、E 9、nが1、E 5 {} 1E51 e 5では、c = 1をとることで最小値を取得できます。

次に
、c = 1 0 4 {10 ^ 4}のときの分析を続けます1 04時の場合、電源シーケンスシーケンスは1、1 0 4、1 0 8、1 0 12 {1、10 ^ 4,10 ^ 8,10 ^ {12}}です。1 1 041 081 0。1 2
When =C。1 0. 3 ^ {10}。31 03時の場合、電源シーケンスシーケンスは1、1 0 3、1 0 6、1 0 9、1 0 12 {1,10 ^ 3,10 ^ 6,10 ^ {9}、10 ^ {12}}です。1 1 031 061 091 01 2

c> = 1000の場合、nは4を超えることができないことは簡単にわかります。4を超える場合、c = 1とすると答えが得られます。

したがって、この質問ではcを列挙できます。以来≤1、E 9、N≥3 {a_i≤1e9、N≧3を}愛a1 e 9 3なので、c≤1 e 9 {c≤\ sqrt {1e9}}c1 e 9
パワーシーケンスのai {a_i}を計算するaai≥1 e 14の場合{a_i≥1e14}a1 e 1 4、ループを終了します。

剪定により、時間の複雑さは超えません。

コード

#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