2021年集训(8.26~8.28)

本文总结了2021年集训期间的CCPC网络选拔赛,重点介绍了参赛者面临的统计难题、最长公共子串、最长回文等算法问题,同时揭示了比赛中存在的不正当竞争现象和平台监控缺失的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2021年集训(8.26~8.28)

2021年集训顺利收官,转眼间5周已过,这5周可谓收获满满,如果能在明天的2021CCPC网络选拔赛顺利突围就更好不过了,但是几率可谓相当的小啊,三千多支队伍一起打选拔赛,才决出来几百支队伍,而且其中高手如林,北大的逆十字也来了,这就说明当年的国家队队长周雨扬也来了,一想到此就十分地激动啊。但是不得不说CCPC的网络选拔赛是真的离谱,没任何监控,全靠自觉,作弊的人肯定不少,而且这几年的网选赛后台数据早被喷爆了,还不整改,硬生生地打成OI,就离谱。

统计难题
传送门

//https://vjudge.ppsucxtt.cn/contest/455495#problem/A
#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
using namespace std;
map <string,int> mp;
int main()
{
    char s[15];
    while(gets(s))
    {
        int len=strlen(s);
        if(!len)
            break;
        char t[15]={0};
        for(int i=0;i<len;i++)
        {
            t[i]=s[i];
            mp[t]++;
        }
    }
    while(gets(s))
        printf("%d\n",mp[s]);
    return 0;
}

最长公共子串
传送门

//https://vjudge.ppsucxtt.cn/contest/455495#problem/B
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100005
#define P 131
typedef unsigned long long ull;
int len1,len2;
char s1[N],s2[N];
ull power[N],hs1[N],hs2[N],s[N];
int judge(int mid)
{
    for(int i=1;i<=len1-mid+1;i++)
        s[i]=hs1[i-1+mid]-hs1[i-1]*power[mid];
    int len=len1-mid+1;
    sort(s+1,s+1+len);
    for(int i=1;i<=len2-mid+1;i++)
    {
        int pos=lower_bound(s+1,s+1+len,hs2[i-1+mid]-hs2[i-1]*power[mid])-s;
        if(s[pos]==hs2[i-1+mid]-hs2[i-1]*power[mid])
            return 1;
    }
    return 0;
}
int main()
{
    power[0]=1;
    for(int i=1;i<N;i++)
        power[i]=power[i-1]*P;
    scanf("%s",s1+1);
    scanf("%s",s2+1);
    len1=strlen(s1+1);
    len2=strlen(s2+1);
    for(int i=1;i<=len1;i++)
        hs1[i]=hs1[i-1]*P+s1[i]-'a'+1;
    for(int i=1;i<=len2;i++)
        hs2[i]=hs2[i-1]*P+s2[i]-'a'+1;
    int l=1,r=min(len1,len2),ans=0;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(judge(mid))
            ans=mid,l=mid+1;
        else
            ans=ans,r=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}

最长回文
传送门

//https://vjudge.ppsucxtt.cn/contest/455495#problem/C
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 110005
char s[N],t[2*N];
int Len[2*N];
int init(int len)
{
    t[0]='[';
    for(int i=1;i<=2*len-1;i+=2)
    {
        t[i]='$';
        t[i+1]=s[i/2];
    }
    t[2*len+1]='$';
    t[2*len+2]=']';
    t[2*len+3]=0;
    return 2*len+1;
}
int manacher(int len)
{
    int pos=0,mx=0,ans=0;
    for(int i=1;i<=len;i++)
    {
        //定位
        if(i<mx)
            Len[i]=min(Len[2*pos-i],mx-i);
        else
            Len[i]=1;
        //拓展
        while(t[i-Len[i]]==t[i+Len[i]])
            Len[i]++;
        //更新
        if(i+Len[i]>mx)
        {
            pos=i;
            mx=i+Len[i];
        }
        ans=max(ans,Len[i]);
    }
    return ans-1;
}
int main()
{
    while(scanf("%s",&s)!=EOF)
    {
        int slen=strlen(s);
        int tlen=init(slen);
        printf("%d\n",manacher(tlen));
    }
    return 0;
}

Power Strings
传送门

//https://vjudge.ppsucxtt.cn/contest/455495#problem/F
#include <stdio.h>
#include <string.h>
#define N 1000005
char s[N];
int nx[N];
void getnext(int len)
{
    int j=-1;
    nx[0]=-1;
    for(int i=1;i<len;i++)
    {
        while(s[j+1]!=s[i]&&j>-1)//不同则回溯
            j=nx[j];
        if(s[j+1]==s[i])//相同则向后
            j++;
        nx[i]=j;
    }
}
int main()
{
    while(scanf("%s",&s)!=EOF)
    {
        if(strcmp(s,".")==0)
            break;
        memset(nx,0,sizeof(nx));
        int len=strlen(s);
        getnext(len);
        int n=len-nx[len-1]-1;
        if(len%n==0)
            printf("%d\n",len/n);
        else
            printf("1\n");
    }
    return 0;
}

A Secret
传送门

//https://vjudge.ppsucxtt.cn/contest/455495#problem/G
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000005
#define MOD 1000000007
char s1[N],s2[N];
int nx[N];
long long ans[N];
void getnext(int len)
{
    nx[0]=nx[1]=0;
    for(int i=1;i<len;i++)
    {
        int j=nx[i];
        while(s2[j]!=s2[i]&&j)
            j=nx[j];
        if(s2[j]==s2[i])
            nx[i+1]=j+1;
        else
            nx[i+1]=0;
    }
}
void kmp(int len1,int len2)
{
    int j=0;
    for(int i=0;i<len1;i++)
    {
        while(s2[j]!=s1[i]&&j)
            j=nx[j];
        if(s2[j]==s1[i])
            j++;
        ans[j]++;
        if(j==len2)
        {
            j=nx[j];
            if(j>len2)
                j=0;
        }
    }
}
int main()
{
    int _;
    scanf("%d",&_);
    while(_--)
    {
        memset(nx,0,sizeof(nx));
        memset(ans,0,sizeof(ans));
        scanf("%s",&s1);
        scanf("%s",&s2);
        int len1=strlen(s1);
        int len2=strlen(s2);
        reverse(s1,s1+len1);
        reverse(s2,s2+len2);
        getnext(len2);
        kmp(len1,len2);
        for(int i=len2;i>=1;i--)
            ans[nx[i]]+=ans[i];
        long long sum=0;
        for(int i=1;i<=len2;i++)
            sum=(sum+ans[i]*i)%MOD;
        printf("%lld\n",sum);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值