
示例 1
输入
4
输出
bbaa
示例 2
输入
100
输出
jihgfeeddccbbaa
思路:把这题拆成两个部分,第一个部分是确定最小长度,第二个部分是确定最小字符序
给出一个定义:交换的次数等于字符串的逆序对个数
例如ba,b比a大,逆序对个数是1,cba,b产生1个,a产生两个,逆序对是3。
于是很自然想到,在长度相同的情况下,逆序数越多,交换次数越多。为了保证逆序对尽可能的多,我们构造的字符串尽量是递减序列。
例如:
长度 len = 1时,我们构造的字符串要形如 a,逆序对个数为 0,交换次数为 0。
当长度 len = 2 时,我们构造的字符串要形如 ba,逆序对个数 1,交换次数为 1。
当长度 len=3 时,我们构造的字符串要形如 cba,逆序对个数为 3,交换次数为 3。
⋯
当长度 len=26时,我们构造的字符串得为 zyxwvutsrqponmlkjihgfedcba,逆序对个数为 325,交换次数为 325。
题目中的要求是V最大是10000,所以这个325是远远达不到要求的,所以势必有字符是要重复的。
那接下来我们考虑一个新的问题,在只有a,b,c的情况下,构造出一个长度为7,交换次数最多的字符串,怎么想呢?给定一个字符串,插入一个字符,逆序对增加的个数=前面比该字符小的字符数量 + 后面比该字符大的字符数量。所以呢,每次我们只要插入当前字符串中字符个数最少的字符就好了~所以我们有三种方案cccbbaa,ccbbbaa,ccbbaaa,字符序最小的话,当然是ccbbaaa了。
不过我们现在的问题是:在给定的长度为len的字符串,其最大逆序数个数是多少?为什么要求这个呢,因为当我们找到第一个长度len,其最大逆序数>=V时,我们就可以从这个长度产生字符序最小的字符串,而这个len也就是最小的长度。
那回到正题,有了上边的例子,我们明白了,一个长度为len的字符串里边,要达到最大逆序数,每个字符个数最好是平均分配的,又要字符序最小,个数多的应该是字符顺序小的。字符数量为len/26+1(向下取整)的字符有len%26个,字符数量为len/26的字符有26-len%26个。那给定len,最大的交换次数的公式如下所示:

解释一下每一项吧,拿前半部分来说,含义是抽取每一个长度为len/26+1的字母,用这个长度乘剩下的长度也就是len-(len/26+1),这样就是该字母产生的逆序对,由于每个
代码如下所示:
int get_max(int len){
return ((len - (len / 26 + 1)) * (len / 26 + 1) * (len % 26) + (26 - len % 26) * (len / 26) * (len - len / 26)) / 2;
}
在上面我们已经求出了最小的长度len,也就是第一个len使得max(len)=X>=V,那么我们肯定也可以改变字符顺序,构造出逆序对个数为X,X-1......0的字符串。
于是我们可以从字符串的第一个位置往后构造,具体为:
从小到大枚举字符ch(ch∈[a~z]),判断当前位置的字符为ch是否可以构造出长度为len,且逆序对大于等于V的字符串。
最后若第pos个位置放置ch可以构造出长度为len,逆序对个数大于等于V的字符串,我们就令第pos个位置的字符串为ch,继续构造,否则在pos放下一个字符ch+1,继续构造。
具体代码如下所示:
#include<bits/stdc++.h>
using namespace std;
int V , len , now , cnt[27] , sum[27];
int get_max(int len){
return ((len - (len / 26 + 1)) * (len / 26 + 1) * (len % 26) + (26 - len % 26) * (len / 26) * (len - len / 26)) / 2;
}
bool check(int x , int n){
memset(cnt , 0 , sizeof(cnt));//cnt记录后面n个位置放置的对应字符数量
int add1 = 0 , add2 = 0;
for(int j = 26 ; j >= x + 1 ; j --) add1 += sum[j];//1~pos-1里边比当前插入字符大的字符数量
sum[x] ++ ;//当前字符数量增加1
for(int L = 1 ; L <= n ; L ++){
//ma保存最大逆序对个数 L-1-cnt[j]+num
//L-1-cnt[j]是当前字符之后的比当前字符小的字符数量的最大值
//num是1~pos+L-1前的比当前放置字符字典序大的字符数量
int ma = -1 , pos = 0 , num = 0;
for(int j = 26 ; j >= 1 ; j --){
if(L - 1 - cnt[j] + num > ma){
ma = L - 1 - cnt[j] + num;
pos = j;
}
num += sum[j];
}
add2 += ma , cnt[pos] ++;
}
if(now + add1 + add2 >= V) {
now += add1;
return true;
}
else {
sum[x] -- ;
return false;
}
}
signed main()
{
string ans = "";
cin >> V;
for(int i = 1 ; ; i ++) {
if(get_max(i) >= V){
len = i;
break ;
}
}
for(int i = 1 ; i <= len ; i ++){
for(int j = 1 ; j <= 26 ; j ++){
if(check(j , len - i)){
ans += char(j + 'a' - 1);
break ;
}
}
}
cout << ans << '\n';
return 0;
}
转载自蓝桥云课中的思路~
其实其中第pos之后的每个位置选择一个字符颇有点动态规划的味道,很nb的思路很好的一题~
我需要用任何语言编写一个算法,根据3个因素对数组进行排序。我以度假村为例(如Hipmunk)。假设我想去度假。我想要最便宜的地方、最好的评论和最多的景点。但是,显然我找不到在所有3个中都排名第一的方法。Example(assumingthereare20importantattractions):ResortA:$150/night...98/100infavorablereviews...18of20attractionsResortB:$99/night...85/100infavorablereviews...12of20attractionsResortC:$120/night
我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我有一个对象如下:[{:id=>2,:fname=>"Ron",:lname=>"XXXXX",:photo=>"XXX"},{:id=>3,:fname=>"Dain",:lname=>"XXXX",:photo=>"XXXXXXX"},{:id=>1,:fname=>"Bob",:lname=>"XXXXXX",:photo=>"XXXX"}]我想按fname排序,不区分大小写,所以它会导致编号:1,3,2我该如何排序?我正在尝试:@people.sort!{|x,y|y[:fname]x[:fname]}但这没有任何效果。 最佳答案
有人可以告诉我如何根据自定义字符串对嵌套数组进行排序吗?比如有没有办法排序:[['Red','Blue'],['Green','Orange'],['Purple','Yellow']]“橙色”、“黄色”,然后是“蓝色”?最终结果如下所示:[['Green','Orange'],['Purple','Yellow'],['Red','Blue']]它不是按字母顺序排序的。我很想知道我是否可以定义要排序的值以实现上述目标。 最佳答案 sort_by对于这种排序总是非常方便:a=[['Red','Blue'],['Green','Ora
我有以下现有的Dog对象数组,它们按age属性排序:classDogattr_accessor:agedefinitialize(age)@age=ageendenddogs=[Dog.new(1),Dog.new(4),Dog.new(10)]我现在想插入一条新的狗记录,并将它放在数组中的正确位置。假设我想插入这个对象:another_dog=Dog.new(8)我想把它插入到数组中,让它成为数组中的第三项。这是一个人为的示例,旨在演示我特别想如何将一个项目插入到现有的有序数组中。我意识到我可以创建一个全新的数组并重新对所有对象进行排序,但这不是我的目标。谢谢!
我有一个这样的哈希{55=>{:value=>61,:rating=>-147},89=>{:value=>72,:rating=>-175},78=>{:value=>64,:rating=>-155},84=>{:value=>90,:rating=>-220},95=>{:value=>39,:rating=>-92},46=>{:value=>97,:rating=>-237},52=>{:value=>73,:rating=>-177},64=>{:value=>69,:rating=>-167},86=>{:value=>68,:rating=>-165},53=>{:va
如何在ruby中先根据值然后根据键对散列进行排序?例如h={4=>5,2=>5,7=>1}将排序为[[7,1],[2,5],[4,5]]我可以根据值进行排序h.sort{|x,y|x[1]y[1]}但我不知道如何根据值进行排序,然后在值相同时键入 最佳答案 h.sort_by{|k,v|[v,k]}这使用了Array的事实混入Comparable并定义逐元素。注意上面等价于h.sort_by{|el|el.reverse}相当于h.sort_by(&:reverse)这可能会或可能不会更具可读性。如果你知道Hashes一般都是先
在Ruby中,默认排序将空字符串放在第一位。['','g','z','a','r','u','','n'].sort给予:["","","a","g","n","r","u","z"]但是,在end处需要空字符串是很常见的。做类似的事情:['','g','z','a','r','u','','n'].sort{|a,b|a[0]&&b[0]?ab:a[0]?-1:b[0]?1:0}工作并给予:["a","g","n","r","u","z","",""]但是,这不是很可读,也不是很灵活。在Ruby中是否有一种合理且干净的方法让sort将空字符串放在最后?只映射到一个没有空字符串的数组,