牛客春招刷题训练营 - 2025.5.7 题解

活动地址:牛客春招刷题训练营 - 编程打卡活动

Easy 小美的排列询问

简要题意

询问一个排列中两个数是否相邻。

Solution

记录每个数的位置,判断绝对差是否为 即可。

Code

void R()
{
	int n,x,y;
	cin>>n;
	vector<int> p(n+1);
	for (int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		p[x]=i;
	}

	cin>>x>>y;
	cout<<(abs(p[x]-p[y])==1?"Yes":"No");
	return;
}

Medium 小红的字符串构造

简要题意

给一个字符串 ,构造一个字符串 ,使得 中每个字母的出现次数与 相同,且没有一个位置 使得 ,或报告无解。

Solution

记录每个字母出现位置,先按对应字母出现次数对位置排序,记排序得到的位置数组为

中第一个字母对应的位置段挪到最后,记为

,若有交则无解,否则得到构造。

Code

void R()
{
	string s,t;
	cin>>s;

	t=s;
	int n=s.size();
	vector<int> A,B;

	vector<vector<int>> pos(26);
	for (int i=0;i<n;i++)
		pos[s[i]-'a'].push_back(i);
	sort(pos.begin(),pos.end(),[&](auto &x,auto &y)
	{
		return x.size()>y.size();
	});
	pos.push_back(pos[0]);
	for (int i=0;i<26;i++)
		for (int p:pos[i])
			A.push_back(p);
	for (int i=1;i<=26;i++)
		for (int p:pos[i])
			B.push_back(p);
	for (int i=0;i<n;i++)
		t[B[i]]=s[A[i]];
	for (int i=0;i<n;i++)
		if (s[i]==t[i])
		{
			cout<<-1;
			return;
		}
	cout<<t;
	return;
}

Hard [ZJOI2010]COUNT 数字计数

简要题意

对区间 内自然数的各个数位,求 分别出现了多少次。

Solution

只要能求 的答案 即为原题的答案,下面考虑如何求

在十进制下有 位。

表示考虑到十进制下第 位(从高位到低位考虑,个位为第零位)为 ,当前以确定的数位是否与 的前 位一致的前提下,前 位有多少种方案,有转移:

其中 的第 位。

则数位 的出现次数为

Code

void R()
{
	auto solve=[&](i64 x)->vector<i64>
	{
		vector<i64> cnt(10),dig,pw;
		if (!x) return cnt;
		int L=0;
		i64 tmp=1;
		while (x>=tmp)
		{
			pw.push_back(tmp);
			dig.push_back(x/tmp%10);
			tmp*=10;
			L++;
		}
		pw.push_back(tmp);

		vector<vector<array<i64,2>>> dp(L,vector<array<i64,2>>(10));
		dp[L-1][dig[L-1]][1]=1;
		for (int i=1;i<dig[L-1];i++)
			dp[L-1][i][0]=1;
		for (int i=L-1;i;i--)
		{
			for (int j=1;j<10;j++)
				dp[i-1][j][0]++;
			for (int j=0;j<10;j++)
			{
				for (int k=0;k<10;k++)
				{
					dp[i-1][k][0]+=dp[i][j][0];
					if (k<dig[i-1])
						dp[i-1][k][0]+=dp[i][j][1];
				}
				dp[i-1][dig[i-1]][1]+=dp[i][j][1];
			}
		}

		for (int i=0;i<L;i++)
			for (int j=0;j<10;j++)
				cnt[j]+=dp[i][j][0]*pw[i]+dp[i][j][1]*(x%pw[i]+1);
		return cnt;
	};


	i64 a,b;
	cin>>a>>b;
	auto A=solve(a-1),B=solve(b);
	for (int i=0;i<10;i++)
		cout<<B[i]-A[i]<<" \n"[i==9];
	return;
}
#牛客春招刷题训练营#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务