马蹄集第八次OJ赛

目录

 字符串构造

s的排列

 五彩斑斓的串

密码

 建立数据库

最漂亮的工艺品


马蹄集第八次OJ赛_第1张图片

 字符串构造


难度:黄金
0时间限制:1秒
巴占用内存:128M
你有一个字符串t,它由n个字母组成。定义一个字符串s的子串为s[l.],表示从
位置1到?构成的一个新的串。
你的目标是构造一个字符串s,使得它的可能长度最小,要求s中存在飞个位置讠,可
以找到k个以i为出发点的子串t。

//
// Created by abner on 2023/8/10.
//
#include 
using namespace std;
const int N = 1e5 + 7;
int n,k,pi[N];
char s[N];
void prefix_function(char *s,int len){
    for (int i = 1;i < len;i++){
        int j=pi[i-1];
        while (j>0 && s[i] != s[j])
        j=pi[j-1];
        if (s[i] == s[j])
        j++;
        pi[i]=j;
    }
}
int main(){
    cin >> n >> k >>s;
    prefix_function(s,n);
    for (int i=1;i<=k;i++)
        for (int j=0;j

马蹄集第八次OJ赛_第2张图片

s的排列


难度:黄金
0时间限制:1秒
巴占用内存:128M
给两个字符串S1和s2,判断s2中是否有s1的排列。
如果是返回
true
,否则返回
false
s1的排列指的是s1字符的不同排列。
格式
输入格式:第一行输入字符串S1;
第二行输入字符串S2。
输出格式:输出小写的
true或
false 

//
// Created by abner on 2023/8/10.
//
#include 
using namespace std;
string s1,s2;
int main(){
    cin >>s1;
    cin >>s2;
    int l1 = s1.length(),l2 = s2.length();
    if(l1>l2) {
        cout << "false";
        return 0;
    }
        vector a1(26),a2(26);
        for (int i=0;i

马蹄集第八次OJ赛_第3张图片

 五彩斑斓的串


号难度:钻石
0时间限制:1秒
巴占用内存:128M
小码哥是一个喜欢字符串的男孩子。
小码哥在研究字典序的性质。他发现他可以通过改变字母表的顺序来改变两个字符串的
大小关系。
例如,通过将现有的字母表顺序“abcdefghijklmnopqrstuvwxyz”改为
“abcdefghijk1 onmpqrstuvwxyz”,字符串“omm”会小于“mom'。
现在小码哥有个字符串,对于其中的一个字符串,如果存在某种字母表顺序,使得它
在这个字符串中字典序最小,那这个字符串就是一个五彩斑斓的串。
现在小码哥想找出所有五彩斑斓的串,由于小码哥忙于他的研究,找出所有五彩斑斓的
串的重任被交到了你的身上。

//
// Created by abner on 2023/8/10.
//
#include 
using namespace std;
const int N=3e5 + 7;
int n,ans[N],cnt;
string s[N];
char tmp[N];

struct TRIE {
    int nex[N][26], id, m[26][26], A[30], B[30];
    bool ed[N];

    void insert(string s) {//插入字符串,p是节点号
        int p = 0, l = s.size();
        for (int i = 0; i < l; i++) {
            int c = s[i] - 'a';
            if (!nex[p][c])
                nex[p][c] = ++id;//如果没有,就添加结点
            p = nex[p][c];
        }
        ed[p] = 1;
    }

    bool check(string s) {
        memset(m, 0, sizeof(m));
        int p = 0, l = s.size();
        for (int i = 0; i < l; i++) {
            int c = s[i] - 'a';
//1.看有没有更短的前缀是已知字符串。P是当前扫的字符的
            if (ed[p])
                return false;
//2.看是否有兄弟间的关系矛盾
            for (int j = 0; j < 26; j++)
                if (nex[p][j] && m[c][j] > 0 && j != c)
                    return false;
            //3.更新前序和后续的节点组合
            A[0] = B[0] = 0;
            for (int j = 0; j < 26; j++) {
                if (nex[p][j] && j != c) {
                    m[c][j] = -1;
                    m[j][c] = 1;
                    for (int k = 0; k < 26; ++k) {
                        if (m[c][k] == 1) {
                            A[++A[0]] = k;
                            m[j][k] = 1;
                            m[k][j] = -1;
                        }
                        if (m[j][k] == -1) {
                            B[++B[0]] = k;
                            m[c][k] = -1;
                            m[k][c] = 1;
                        }
                    }
                }
            }
            for (int j = 1; j <= A[0]; j++)
                for (int k = 1; k <= B[0]; k++) {
                    m[A[j]][B[k]] = -1;
                    m[B[k]][A[j]] = 1;
                }
            p = nex[p][c];
        }
        return true;
    }
}trie;

    int main(){
        cin >>n;
        for (int i = 1;i<=n;i++){
            cin >> s[i];
        trie.insert(s[i]);
    }
    for(int i=1;i<=n;i++){
        if (trie.check(s[i])){
            ans[++cnt] = i;
            }
    }
    cout <

马蹄集第八次OJ赛_第4张图片

密码


难度:钻石
©时间限制:1秒
巴占用内存:128M
小码哥,小码妹和他们的临时伙伴小码弟、小码姐已经找到了和谐寺。然而和谐寺大门
紧闭,就连小码妹的运气也没好到能打开它。
不久他们发现了一个字符串S(1≤|S≤1000000),刻在和谐寺大门下面的岩石上。
小码哥猜想那一定是打开寺庙大门的密码,于是就大声将字符串朗读了出来,然而并没
有什么事发生。于是小码哥又猜想密码一定是字符串S的子串T。
小码姐认为T是S的前缀,小码弟认为T是S的后缀,小码妹却认为T应该是S中
间的某一部分。小码哥选择子串T来满足所有伙伴们的想法。同时,在所有可以被接
受的子串变形中,小码哥选择了最长的一个(因为小码哥喜欢长的字符串)当小码哥大
声读出子串T时,寺庙的大门开了(也就是说,你需要找到既是S的前缀又是S的后
缀同时又在S中间出现过的最长子串)。
现在给你字符串S,你需要找到满足上述要求的子串T。 

//
// Created by abner on 2023/8/10.
//
#include 
using namespace std;
const int N=1e6 + 7;
int len,pi[N];
char s1[N],s2[N],s3[N];
void prefix_function(char *s,int len) {
    for (int i = 1; i < len; i++){
        int j = pi[i - 1];
    while (j > 0 && s[i] != s[j])
        j = pi[j - 1];
    if (s[i] == s[j])
        j++;
    pi[i] = j;
    }
}
    int main(){
        cin >>s1;
        len = strlen(s1);
        strcpy(s2,s1 + 1);
        s2[strlen(s2)-1]='\0';
        prefix_function(s1,len);

        int temp = pi[len -1];
        while (temp){
            strncpy(s3,s1,temp);
            s3[temp]='\0';
            if (strstr(s2,s3)){
                cout << s3;
                return 0;
            }
            temp = pi[temp - 1];
        }
        cout <<"Just a legend";
        return 0;
    }













马蹄集第八次OJ赛_第5张图片

 建立数据库


难度:黄金
0时间限制:5秒
巴占用内存:128M
新用户注册时,将向系统发送一则内容为其用户名的请求,如果该用户名尚未存在于系
统数据库内,则将该用户名插入数据库,同时用户得到回应信息
OK
表示其已经成
功注册。如果用户请求的用户名已经存在于数据库内,那么系统将产生一个新的用户名
并将其加入数据库。新用户名由用户请求的用户名与正整数。构成,。为使"用户
名1"尚未存在于数据库内的最小的i。
格式
输入格式:第一行一个整数n(1 接下来几行,每行表示用户向系统发出的一则请求。
每行内容均非空且均为由至多32个小写拉丁字母组成的字符串。
输出格式:行,每行表示系统对一则请求做出的回应。

//
// Created by abner on 2023/8/10.
//
#include 
using namespace std;
const int N = 1e5 +7;
int n;
char str[35];
struct TRIE{
int nex [N][26],cnt,exist [N];

    void insert(char *s,int l) {//插入字符串
        int p = 0;
        for (int i = 0; i < l; i++) {
            int c = s[i] - 'a';
            if (!nex[p][c])
                nex[p][c] = ++cnt;//如果没有,就添加结点
            p = nex[p][c];
        }
        exist[p]++;
    }
        int find(char*s,int l){//查找字符串
            int p=0;
            for (int i=0;i>n;
    while (n--){
        cin >>str;
        int temp = trie.find(str,strlen(str));
        if (!temp)
            cout <<"OK"<

马蹄集第八次OJ赛_第6张图片

最漂亮的工艺品


难度:黄金
0时间限制:1秒
巴占用内存:128M
小码哥和小码妹是一对好朋友。
他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的,而且由于机器的要
求,他们只能做到把这个工艺品最左边的方块放到最右边。
他们想知道,在仅这一种操作下,最漂亮的工艺品能多漂亮。
两个工艺品美观的比较方法是,从头开始比较,如果第i个位置上方块不一样,那么谁
的瑕疵度小,那么谁就更漂亮,如果一样那么继续比较第i+1个方块。如果全都一
样,那么这两个工艺品就一样漂亮。
格式
输入格式:第一行一个整数n,代表方块的数目;
第二行n个整数,表示方块瑕疵度的值。 

//
// Created by abner on 2023/8/10.
//
#include 
using namespace std;
const int N=3e5 +7;
int n,a[N],ans;
int func(int *a,int n) {
    int k = 0, i = 0, j = 1;
    while (k < n &&i < n && j < n){
        if (a[(i + k) % n] == a[(j + k) % n]) {
            k++;
        }  else{
            a[(i + k) % n] > a[(j + k) % n] ? i = i + k + 1 : j = j + k + 1;
            if (i == j)
                i ++;
            k = 0;
        }
    }
    return min(i, j);
}
int main(){
    cin >>n;
    for (int i=0;i>a[i];
    ans = func(a,n);
    for (int i = 0;i < n;i++)
        cout <

你可能感兴趣的:(马蹄集,算法,c++)