Week 15实验

C - TT 的神秘任务 - X

TT 的神秘任务系列。
这一次,TT 得到了一个长度为 N 的字符串,任务要求在原字符串中至多删去一个字符,使得字符串的字典序尽可能小。
字符串字典序的比较优先级如下:
从左往右第一个不同字符的 ASCII 值的大小关系
字符串长度
Input第一行给出 N(2 ≤ N ≤ 2e5)。
第二行给出一个长度为 N,且仅包含小写字母的字符串。Output输出字典序最小的字符串。

Examples

Input

3
aaa

Output

aa

Input

5
abcda

Output

abca

解题思路:

这是一道思维上比较单一的题目,但是自己没能够在短时间内想出正确的逻辑,相反,自己最初做的时候采取了完全暴力的解决方案,其实感觉当时做题时有些过于莽撞,一种试错的心态在写程序时是完全不可取的,其既影响正确方向上的思考,也影响心情。发现自己在做程序时还存在的一个问题便是过于依靠大脑去思考,其实有些题目用笔写一下是更有效的,这道题目自己前前后后花费45分钟,确实暴漏了自己很多缺点。
讲一下这个题目,题目总体来讲不是很难,但需要一种反射式的思维,这与平常的见多识广或是凭空多思考一些问题有关。对于删除其中的某一个字符,我们可以理解成字符后面的所有字符整体向前移一位,这个问题我们可以简单的将其抽象为一个连续的函数图像的平移问题,我们的最终追求是选择某一点之后的图像进行左移,使得原图像最先能够高于平移后的函数图像,很显然我们我在下降区间中去找,而且是第一个下降区间的第一个元素。而这时,脱离图像,我们会发现这道题目的本质好像是在维护一个单调非递减的序列。自己在这个题目上做的不够好,感觉还是对于序列单调性的思维深度不够,有待加强。

#include<iostream>
#include<string>
using namespace std;
int N;
string s;
int label=0;
int main()
{
	cin>>N;
	cin>>s;
	for(int i=1;i<N;i++)
	{
		if(s[i]>=s[i-1])
		label=i;
		else
		break;
	}
	string fun=s.substr(0,label)+s.substr(label+1,N-label-1);
	cout<<fun<<endl;
}在这里插入代码片

D - 瑞瑞爱上字符串

瑞瑞最近迷上了字符串,因此决定出一个字符串的题。
给定两个正整数 N、K,考虑所有由 N - 2 个 a 和 2 个 b 组成的字符串,要求输出其中字典序第 K 小的。
例如当 N = 5 时,共有如下 10 种组成方式:
aaabb
aabab
aabba
abaab
ababa
abbaa
baaab
baaba
babaa
bbaaa

Input

多组数据,第一行给定 T,表示数据组数。(1 ≤ T ≤ 1e4)
对于每组数据,给出两个正整数 N、K。(3 ≤ N ≤ 1e5, 1 ≤ K ≤ min(2e9, N * (N-1) / 2 ))
N 的总和不会超过 1e5。

Output

对于每组数据,输出长度为 N 的字典序第 K 小的字符串。

Example

Input

7
5 1
5 2
5 8
5 10
3 1
3 2
20 100

Output

aaabb
aabab
baaba
bbaaa
abb
bab
aaaaabaaaaabaaaaaaaa

解题思路:

对于本道题目而言,感觉这更像是一道数学题,思路很简单,但就是没做出来。。这个题目的要求不是很高,题目中明确强调N的总和不会超过1e5,但自己做题的时候就是没看见。。1e5的限制下足以满足暴力求解的要求,但不过,我们还是最好在此基础上温习以下二分做法,模拟期间,自己的思路很明确,但是二分的接口总是处理不好,通过这道题目,我们再次了解一下二分。二分的写法基本上是固定的,一般严谨的写法会保留4个变量,l,r,mid,ans.二分的处理可以求解四种情况,1.大于等于的最小值。2.大于的最小值。3,小于等于的最大值。4,小于的最大值。在这里,是按自己的预想思路进行选择的。希望通过这次我们能够记住二分的标准写法,不要再出现懂思想但写不出来的情况。(因为那样真的很影响心情),另外注意一下,二分通常要使用long long数据类型,脑海中要时刻注意。

#include<iostream>
#include<string>
using namespace std;
long long T,N,K;
long long a,b;
long long erfen(long long K)
{
	long long l=1;
	long long r=N;
	long long mid=(r+l)/2;
	long long ans=0;
	while(l<=r)
	{
		if(mid*(mid-1)/2<K)
		l=mid+1;
		else
		{
			ans=mid;
			r=mid-1;
		}
		mid=(r+l)/2;
	}
	return ans;
}
int main()
{
	cin>>T;
	while(T--)
	{
		cin>>N>>K;
		long long a=erfen(K);
		long long b=K-(a-1)*(a-2)/2;
		for(int i=1;i<=N;i++)
		{
			if((i!=N-a+1)&&(i!=(N-b+1)))
			cout<<'a';
			else
			cout<<'b';
		}
		cout<<endl;
	}
}在这里插入代码片
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值