蓝桥杯 历届试题 字串排序

【蓝桥杯】历届试题 字串排序

这个题目题目只过了70%,剩下30%有点思路,但还没想出具体怎么写,但自己在网上没看到比较好的答案,就把自己的写一下,希望大家可以给点剩下30%的思路。

题目描述:

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。

在冒泡排序中,每次只能交换相邻的两个元素。

小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符,则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。

例如,对于字符串 lan 排序,只需要 1次交换。对于字符串 qiao 排序,总共需要4次交换。

小蓝的幸运数字是 ,他想找到一个只包含小写英文字母的字符串,对这个串中的字符进行冒泡排序,正好需要V 次交换。请帮助小蓝找一个这样的字符串。如果可能找到多个,请告诉小蓝最短的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。请注意字符串中可以包含相同的字符。

输入格式

输入一行包含一个整数 ,为小蓝的幸运数字。

输出格式

输出一个字符串,为所求的答案。

样例输入

4

样例输出

bbaa

样例输入

100

样例输出

jihgfeeddccbbaa

评测用例规模与约定

在这里插入图片描述

试题分析

需要交换的次数,实则就是字符串的逆序数,题目需要求最短的字串,可先求逆序数可以大于等于V的最短的字串的长度。对于长r的字串,其最大逆序数可达r*(r-1)/2,(这里先不考虑英文字母只有26个)。找到相应的长度时,计算最大逆序数-V 的差(这里设为t),然后将最大逆序的字串改变,使其逆序数减少t即可。
具体如何改变才可达到题目要求呢?先从后向前然字母重复两次,同上面两个输出样例一样,这样每两个相同字母,逆序数减一。如果全变成了两个还没达到t呢,即t>r/2时,那接下来重复三次即可。每有三个相同的字母,逆序数将减少3。t最大是r-2,r/3*3 最小是r-2,故全变成3个相同一定可以达到t。下面先上第一次上交简化后的代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int N = 1e5+5;
char str[N];
int main(){//字母只有26个,数大了就会超,剩下的还要分情况 
//	ios::sync_with_stdio(false);
//	cin.tie(false);
	int n; 
	cin>>n;
	int r=0;
	while(r*(r+1)/2<n)r++;
	r++;
//	cout<<r<<endl;
	int t=(r-1)*r/2-n;
//	cout<<t<<endl;
	str[r-1]='a';
	for(int i=r-2;i>=0;i--){		
		if(t>r/2){
			str[i]=str[i+1];
			i--;
			str[i]=str[i+1];
			i--;
			t-=3;
		}else if(t>0){
			str[i]=str[i+1];
			i--;t--;
		}
		if(i>=0)str[i]=str[i+1]+1;
	}
	puts(str);
	return 0;
}

在这里插入图片描述
只过了70%,然后分析了一下,字母只有26个,这么算的话V一大就会输出ASCII码比z大的字符了,然后思考了一下V比较大的情况,字串的长r是计算出来了,用下面这段代码可以计算r>26的情况下的r,但具体字串还没想到怎么算,想问问有没有大佬有好的思路。

		r=26;
		int Max=(r-1)*r/2;
		while(Max<n){
			r++;
			int k=r/26;
			int l=r%26;
			Max=(r-1)*r/2;
			Max-=k*(k-1)/2*26;
			Max-=k*l;
		}
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值