CodeForces - 128B (2020.3.29训练G题)

Problem
One day in the IT lesson Anna and Maria learned about the lexicographic order.

String x is lexicographically less than string y, if either x is a prefix of y (and x ≠ y), or there exists such i (1 ≤ i ≤ min(|x|, |y|)), that xi < yi, and for any j (1 ≤ j < i) xj = yj. Here |a| denotes the length of the string a. The lexicographic comparison of strings is implemented by operator < in modern programming languages​​.

The teacher gave Anna and Maria homework. She gave them a string of length n. They should write out all substrings of the given string, including the whole initial string, and the equal substrings (for example, one should write out the following substrings from the string “aab”: “a”, “a”, “aa”, “ab”, “aab”, “b”). The resulting strings should be sorted in the lexicographical order. The cunning teacher doesn’t want to check all these strings. That’s why she said to find only the k-th string from the list. Help Anna and Maria do the homework.

Input
The first line contains a non-empty string that only consists of small Latin letters (“a”-“z”), whose length does not exceed 105. The second line contains the only integer k (1 ≤ k ≤ 105).

Output
Print the string Anna and Maria need — the k-th (in the lexicographical order) substring of the given string. If the total number of substrings is less than k, print a string saying “No such line.” (without the quotes).

题意:输出给定字符串的第k大的子串

用优先队列过的这题,补完这一题的唯一感觉,条件太苛刻了,几乎是卡着2s的边过的,不取消流同步不改scanf压根过不了,就连优先队列的<符号实现写的不好也超了点时(这点我到现在还不理解,friend和单纯bool实现的为啥差时那么多,或是这点时间差正好是压到wa的最后一根稻草?)

做法:建立一个优先队列,字典序小的优先靠前,第一遍遍历将每个单个字符push进队列,定义好结构体记录好每个子串的结尾下标,每次取出队首,k–,pos++,加入新pos位的字符,成为新的字符串,再push,反复如此操作,k=0的时候就结束弹出,输出x.s

AC代码如下:

#include<iostream>
#include<string>
#include<string.h>
#include<queue>
using namespace std;

struct ss
{
	int pos;
	string s;
	bool operator < (const ss &x)const
	{
		if (x.s == s)return pos > x.pos;
		return s > x.s;
	}
};
priority_queue<ss>que;
typedef struct ss ss;
ss x;
char str[100005];

int k;
int main()
{
	ios::sync_with_stdio(false);
	scanf("%s", str + 1);
	scanf("%d", &k);
	int len = strlen(str + 1);
	for (int i = 1; i <= len; i++)
	{
		x.s = "";
		x.s += str[i];
		x.pos = i;
		que.push(x);
	}
	
	while (!que.empty())
	{
		k--;
		x = que.top();
		//cout<<k<<" "<<x.s<<endl;
		que.pop();
		if (!k)
		{
			break;
		
		}
		
		if (x.pos<len)
		{
			x.pos++;
			x.s += str[x.pos];
			que.push(x);
		}
		
		
		
		
	}
	if (k) cout << "No such line." << endl;
	else cout << x.s << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列目,其中包括目E. Kolya and Movie Theatre。 根据目描述,E. Kolya and Movie Theatre问要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值