loj#533. 「LibreOJ Round #6」花煎

非常巧妙的转化。

考虑仅计算半边的序列,那么这样的话 \(len\) 削了一半,要达成的色彩值也开平方了。

问题就转化为,将 \(l\) 拆分为序列 \(a\),使得 \(\sum_{i=1}^{n}(a_i+1)=l\),且使得 \(\prod_{i=1}^{n}a_i \geq k\) 的最小 \(l\)

经过一些计算,可以发现 2 的段不超过一个,3 的段不超过四个,5 的段不超过一个,剩下的全部填充为 4 的段。

记得特判 \(k=1\) 即可,代码如下。

#include<bits/stdc++.h>
using namespace std;
namespace gza{
	#define int long long
	#define pb push_back
	#define MT int TTT=R;while(TTT--)
	#define pc putchar
	#define R read()
	#define fo(i,a,b) for(int i=a;i<=b;i++)
	#define rep(i,a,b) for(int i=a;i>=b;i--)
	#define m1(a,b) memset(a,b,sizeof a)
	namespace IO
	{
		inline int read()
		{
		    int x=0;
		    char ch=getchar();
		    bool f=0;
		    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
		    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
		    if(f) x=-x;
		    return x;    
		}
		template<typename T> inline void write(T x)
		{
		    if(x<0) pc('-'),x=-x;
		    if(x>9) write(x/10);
		    pc(x%10+'0');
		}
	};
	using namespace IO;
	
	int k;
	void solve()
	{
		k=R;
		if(k==1) return void(puts("4"));
		int ans=2e9;
		fo(a,0,1) fo(b,0,4) fo(c,0,1) 
		{
			int res=1;
			if(a) res*=2;
			fo(i,1,b) res*=3;
			if(c) res*=5;
			int kk=(k+res-1)/res;
			ans=min(ans,a*3+b*4+c*6+(int)ceil(log2(kk)/2)*5);
		}
		write(ans*2),puts("");
	}
	void main(){
		MT solve();
	}
}
signed main(){
	gza::main();
}
posted @ 2024-03-22 20:31  luogu_gza  阅读(90)  评论(0)    收藏  举报