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
#include
#include
#include
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<
		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;
}

你可能感兴趣的:(CodeForces - 128B (2020.3.29训练G题))