P6101 [EER2]出言不逊

看到大家都是暴力枚举,但是其实这道题有数学方法。

首先,很明显,第一次找到一个出现次数最大的字符后,每次都是加上这么多同样的字符,这样才能最快。

假设原串长度为 ss,原串中出现次数最大的字符出现过了 nn 次,按照题意,最后需要长度 l\ge l。可以列出方程 s+i=0k2i×nl\large s + \sum_{i = 0}^{k} 2^i \times n \ge l,则化简可得为 s+n+n×(2k+12)l\large s + n + n \times (2^{k+1}-2) \ge l,进一步,k=log2((lsn)÷n+2)1\large k = \lceil \log_2((l - s - n) \div n + 2) - 1 \rceil,带入即可:

#include <bits/stdc++.h>
using namespace std;

#define int __int128

int read()
{
	int x = 0;
	char ch = getchar();
	while (ch >= '0' && ch <= '9')
	{
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x;
}

void write(int x)
{
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}

signed main()
{
	string s;
	int l, cnt = 0;
	cin >> s;
	scanf("\n");
	l = read();
	int now = s.length();
	int len = s.length() - 1;
	map<char, int> mp;
	for (int i = 0; i <= len; i++)
	{
		mp[s[i]]++;
	}
	if (now >= l)
	{
		write(cnt);
		puts("");
		return 0;
	}
	cnt++;
	int maxn = 0;
	for (map<char, int>::iterator it = mp.begin(); it != mp.end(); ++it)
	{
		if (it->second > maxn)
		{
			maxn = it->second;
		}
	}
	now += maxn;
	int rem = l - now;
	int q = ceil(rem * 1.0 / maxn);
	q += 2;
	int ans = ceil(log2(q * 1.0));
	ans--;
	cnt += ans;
	write(cnt);
	puts("");
	return 0;
}
posted @   HappyBobb  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示