codeforces 126B B. Password(kmp+dp)

题目链接:

codeforces 126B


题目大意:

给出一个字符串,找出一个子串既是它的前缀,也是它的后缀,还是一个非后缀也非前缀的子串。


题目分析:

  • 本来挺简单的一个题,最开始想复杂了,还用了后缀数组,醉了。
  • 这个题主要用的是kmp的next数组,首先我们要了解next数组的定义,next[i]表示以i为末尾的子串的后缀与能够匹配的整个串的最长的前缀。
  • 然后我们可以知道后缀与前缀的最长相同的长度,现在是满足后缀和前缀的最长子串的情况。
  • 然后我们利用hash除了以最后一个字符结尾的情况所有的与前缀匹配的长度。
  • 最后我们利用next数组的性质,如果当前的匹配的长度在hash表中找不到,那么证明不存在非前缀与非后缀的子串符合条件,那么x=next[x],也就是跳转到当前位置失配的重新匹配的位置(免去重复匹配的部分),也就是小于当前情况的最大的子串的后缀和前缀匹配的情况,然后再查hash表。知道找到答案为止,找不到答案证明不存在解。

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 1000007

using namespace std;

char s[MAX];
int next[MAX];
int hash[MAX];

void kmp ( int n )
{
    memset ( next , 0 , sizeof ( next ) );
    for ( int i = 2 ; i <= n ; i++ )
    {
        int k = next[i-1];
        while ( k && s[k+1] != s[i] ) k = next[k];
        if ( s[k+1] == s[i] ) next[i]=k+1;
    }
}

int main ( )
{
    while ( ~scanf ( "%s" , s+1 ) )
    {
        int n = strlen ( s+1 );
        kmp ( n );
        memset ( hash , 0  , sizeof ( hash ) );
        for ( int i = 2; i < n ; i++ )
            hash[next[i]] = 1;
        int x = next[n];
        while ( !hash[x] && x ) x = next[x];
        if ( !x ) printf ( "Just a legend" );
        else for ( int i = 1 ; i <= x ; i++ )
            printf ( "%c" , s[i] );
        puts ( "" );
    }

}
### Codeforces Round 933 Div. 3 题目概述 Codeforces Round 933 (Div. 3) 是一场面向较低评级选手的比赛,通常包含多个不同难度级别的编程挑战。这类比赛旨在帮助新手提升算法技能并熟悉竞赛环境。 #### A. 奇偶数分组 在这个问题中,给出一系列整数,目标是将这些数字分成两部分——一部分只含奇数,另一部分仅存偶数。如果可以实现这样的划分,则输出 "YES"; 否则返回 "NO"[^1]。 ```cpp #include <bits/stdc++..h> using namespace std; int main() { int n; cin >> n; vector<int> a(n); bool has_odd = false, has_even = false; for(int i=0; i<n; ++i){ cin>>a[i]; if(a[i]%2==0)has_even=true; else has_odd=true; } cout<<(has_odd && has_even ? "YES\n":"NO\n"); } ``` 此代码片段展示了如何读取输入数据,并通过遍历数组中的每一个元素来检查是否存在至少一个奇数和一个偶数。 #### B. 数字游戏 参与者被给予了一个正整数 \(n\) 和另一个非负整数 \(k\) 。玩家的任务是从 \(n\) 开始连续减去 \(k\) ,直到结果变为零或更小为止。该过程记录下所有的中间值形成序列。询问最终得到的序列长度是多少?[未提供具体引用] ```cpp #include<bits/stdc++.++.h> using namespace std; int main(){ long long n,k; cin>>n>>k; int cnt=0; while(n>=0){ cnt++; n-=k; } cout<<cnt<<"\n"; } ``` 这段程序实现了上述逻辑,即不断减少 `n` 的值直至其变得不再大于等于零,并统计循环次数作为答案的一部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值