#P2067. 第2题-小红的字符串
-
1000ms
Tried: 73
Accepted: 15
Difficulty: 1
所属公司 :
京东
时间 :2024年9月14日
第2题-小红的字符串
思路:模拟+自定义排序
s<t当且仅当 1. s为t的前缀 2. s字典序<t字典序 先把字符串按照题目规则变成符合题意的字符串,根据上述规则写好cmp,排序之后还原对应字符串即可 时间复杂度o(n2log2n)
代码如下
cpp
#include <bits/stdc++.h>
using namespace std;
string a[1005];
bool cmp(string a, string b) {
if(a.size()<b.size()){
string c=b.substr(0,a.size());
if(a==c) return 1;
}
else{
string c=a.substr(0,b.size());
if(b==c) return 0;
}
if (a + b == b + a) {
return a.size() < b.size();
}
return a + b < b + a;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
string s;
cin >> s;
s = ' ' + s;
vector<int>rank(27);
vector<int>c(27);
for (int i = 1; i <= 26; i++) {//修改成排名对应字符
rank[s[i] - 'a' + 1] = i;
c[i] = s[i] - 'a' + 1;
}
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
for (int j = 0; j < a[i].size(); j++) {
a[i][j] = rank[a[i][j] - 'a' + 1] + 'a' - 1;
}
}
sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++) {//还原字符串
for (int j = 0; j < a[i].size(); j++) {
a[i][j] = c[a[i][j] - 'a' + 1] + 'a' - 1;
}
}
for (int i = 1; i <= n; i++) {
cout << a[i] << '\n';
}
return 0;
}
python
def custom_sort(s, words):
s = ' ' + s
rank = [0] * 27
c = [0] * 27
for i in range(1, 27):
rank[ord(s[i]) - ord('a') + 1] = i
c[i] = ord(s[i]) - ord('a') + 1
def transform(word):
return ''.join(chr(rank[ord(ch) - ord('a') + 1] + ord('a') - 1) for ch in word)
def restore(word):
return ''.join(chr(c[ord(ch) - ord('a') + 1] + ord('a') - 1) for ch in word)
def cmp(a, b):
if len(a) < len(b):
if a == b[:len(a)]:
return -1
else:
if b == a[:len(b)]:
return 1
if a + b == b + a:
return len(a) - len(b)
return (a + b) < (b + a)
transformed_words = [transform(word) for word in words]
transformed_words.sort(key=lambda x: (x * 2, len(x)), reverse=False)
transformed_words.sort(key=cmp_to_key(cmp), reverse=False)
return [restore(word) for word in transformed_words]
def cmp_to_key(mycmp):
class K:
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
return K
# 输入处理
s = input().strip()
n = int(input().strip())
words = [input().strip() for _ in range(n)]
sorted_words = custom_sort(s, words)
for word in sorted_words:
print(word)
java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
s = " " + s;
int[] rank = new int[27];
int[] c = new int[27];
for (int i = 1; i <= 26; i++) {
rank[s.charAt(i) - 'a' + 1] = i;
c[i] = s.charAt(i) - 'a' + 1;
}
int n = scanner.nextInt();
String[] a = new String[n + 1];
for (int i = 1; i <= n; i++) {
a[i] = scanner.next();
char[] chars = a[i].toCharArray();
for (int j = 0; j < chars.length; j++) {
chars[j] = (char)(rank[chars[j] - 'a' + 1] + 'a' - 1);
}
a[i] = new String(chars);
}
Arrays.sort(a, 1, n + 1, new Comparator<String>() {
public int compare(String a, String b) {
if (a.length() < b.length()) {
if (b.startsWith(a)) return -1;
} else {
if (a.startsWith(b)) return 1;
}
if ((a + b).equals(b + a)) {
return Integer.compare(a.length(), b.length());
}
return (a + b).compareTo(b + a);
}
});
for (int i = 1; i <= n; i++) {
char[] chars = a[i].toCharArray();
for (int j = 0; j < chars.length; j++) {
chars[j] = (char)(c[chars[j] - 'a' + 1] + 'a' - 1);
}
a[i] = new String(chars);
System.out.println(a[i]);
}
scanner.close();
}
}
题目内容
给小红n个字符串,请你对这n个字符串按照以下规则从小到大排序。
对于任意两个字符串s和t,在排序后应当满足:
若s是t的一个前缀,则s在排序后的下标小于等于t的在排序后的下标。
若存在整数i,使得s的前i−1个字符和t的前i−1个字符相同,且s和t的第i个字符不同,则比较第i个字符的大小关系(字符的大小关系顺序由输入数据给出)。若s的第i个字符小于等于t的第i个字符,则s在排序后的下标小于等于t的在排序后的下标。
容易发现,上述排序方法排序结果是唯一的。
输入描述
第一行输入一个字符串,包含26个互不相同的小写字母。记rank(c)表示字母c是该字符串的第rank(c)个字符,则字母a小于等于字母b当且仅当rank(a)≤rank(b)。
第二行输入一个整数n(1≤n≤1000),表示待排序字符串的数量。
接下来n行,每行一个仅包含小写字符的字符串si(∣si∣≤1000),表示一个待排序的字符串。
输出描述
按照排序后字符串位置下标从小到大的顺序输出n行,每行一个字符串,表示排序的结果。
样例1
输入
abcdefghijklmnopqrstuvwxyz
3
aaa
aac
aaaa
输出
aaa
aaaa
aac
样例2
输入
zyxwvutsrqponmlkjihgfedcba
3
aaa
aac
aaaa
输出
aac
aaa
aaaa