CodeForces - 1373E Sum of Digits(貪心)

題目鏈接:點擊查看

題目大意:設 f( x ) 爲 x 的數位之和,給出一個 n 和一個 k ,求 f(x) + f(x + 1) + \dots + f(x + k) = n 的最小 x ,若不存在,輸出 -1

題目分析:因爲 n 和 k 比較小,所以可以打表,當 k 爲 0 的時候,顯然是 r + 99...999 是最優的,其中 r = n%9,當 k 爲 1 的時候,打表的時間複雜度是 sqrt( 1e16 ) * 8 ,也就是將近 1e9 ,本地可能繃不住,所以可以打到 1e7 左右,然後自己找找規律補齊剩下的幾項就好了,剩下的時間複雜度分別就是 \small \sqrt[3]{1e16}\small \sqrt[4]{1e16}之類的了,本地輕輕鬆鬆搞定

然後說一下正解,因爲 k 最大隻有 9 ,比較顯然的一點就是,至多會進位一次,因爲我們貪心的策略是較低位都放置 9 ,所以個位的進位會涉及到更高位的連續進位,這樣我們不妨設我們最後構造出來的數爲 r + 99...999 + 8 + 99..999 + x ,我們將需要構造的數分爲了五段,因爲說過了,爲了貪心,所以低位需要儘量放 9 ,我們設 x 左邊的第一堆 9 的個數爲 num_9,又因爲如果涉及進位的話,會導致連續進位,所以我們在 num_9 個 9 之前,放置了一個 8 ,到此停止連續進位,剩下的再按照當 k = 0 時貪心放置就好了

因爲最多隻有 1e16,換句話說 num_9 最多隻有 16 ,而個位的 x 也最多隻有 9 種取值,我們可以暴力枚舉 x 和 num_9 ,然後計算此時貪心放置得到的最小值,就好了

代碼:
 

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const LL inf=0x3f3f3f3f3f3f3f3f;

const int N=510;

int n,k;

LL cal(int last,int num_9)
{
	int num=n;
	for(int i=0;i<=k;i++)
	{
		if(last+i<=9)
			num-=last+i+9*num_9;
		else
			num-=last+i-9;
	}
	if(num<0||num%(k+1)!=0)//如果剩下的數小於0了或者不足以恰好分爲k+1份,則此時無解
		return inf;
	num/=k+1;
	LL ans=0;
	if(num<9)//按照k=0時貪心分配即可
		ans=num;
	else
	{
		num-=8;//別忘了需要放上一個8用來截斷連續的9
		ans=num%9;
		for(int i=1;i<=num/9;i++)
			ans=ans*10+9;
		ans=ans*10+8;
	}
	for(int i=1;i<=num_9;i++)
		ans=ans*10+9;
	ans=ans*10+last;
	return ans;
}

LL solve()
{
	LL ans=inf;
	for(int i=0;i<10;i++)//枚舉個位的x
		for(int j=0;j<=16;j++)//枚舉x前有多少個9:num_9
			ans=min(ans,cal(i,j));
	if(ans==inf)
		ans=-1;
	return ans;
}

int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		scanf("%d%d",&n,&k);
		printf("%lld\n",solve());
	}









    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章