• day18


    今天的题好难啊!!!!80/300;

    T1第一眼像个树形DP,推了大约30min无果,改写暴力还写挂了!!!!0/100

    正解:贪心,每次选最小的花费,向上更新看是否合法;

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    struct node{
        int e,fa;
    }a[1010];
    int fa[1010],w[1010];
    int n,ans,total;
    bool v;
    inline int cmp(node x,node y){return x.e<y.e;}
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
        return x*f;
    }
    inline void check(int x,int i)
    {
        if(i==0)return;
        if(w[i]>=x)
        {
            check(x,fa[i]);
        }
        else
        {
            v=0;
            return;
        }
    }
    inline void updata(int x,int i)
    {
        if(i==0)return;
        w[i]-=x;
        updata(x,fa[i]);
    }
    int main()
    {
        n=read(); 
        for(int i=1;i<=n;i++)
        {
            fa[i]=read();a[i].e=read();w[i]=read();
            a[i].fa=i;
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++)
        {
            v=1;
            check(a[i].e,a[i].fa);
            if(v){total++;updata(a[i].e,a[i].fa);}
        }
        cout<<total<<endl;
        return 0;
    }
    View Code

    T2发现答案只在右端点,写了一个O(n/2+n2/2)的算法,拿了60分(吸一口氧可拿80)60/100

     正解,把 l 和 r 丢到一个数组中排序,处理一个 sa 记录全部 l 的和,sp 记录现在在几个区间中,

    遇到一个 l 端点 sa--,sp++;遇到一个 r 端点 先判断是否要更新答案,然后 sp--;复杂度极低;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct node{
        long long l,r;
    }c[210000];
    int n,l[110000],r[110000];
    inline long long maxx(long long x,long long y){return x>y?x:y;}
    inline int cmp(node x,node y)
    {
        return x.l<y.l;
    }
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
        return x*f;
    }
    int main()
    {
        n=read();long long sa=0,sp=0,ans1,ans=-1;
        for(int i=1;i<=n;i++)
        {
            l[i]=read();r[i]=read();
            sa+=l[i];
            c[i].l=l[i];c[i+n].r=1;
            c[i+n].l=r[i];
        }
        sort(c+1,c+1+2*n,cmp);
        for(int i=1;i<=2*n;i++)
        {
            if(c[i].r)
            {
                if(ans<sa+sp*c[i].l){
                    ans1=c[i].l;ans=sa+sp*c[i].l;
                }
                sp--;
            }
            if(!c[i].r)
            {
                sa-=c[i].l;sp++;
            }
        }
        cout<<ans1<<" "<<ans<<endl;
        return 0;
    }
    View Code

    T3写了一个暴力匹配结果炸了???20/100

    把A串以*分割成几个子串,B串*2处理循环,在kmp搞一下,记录以某个字符为起点能匹配完A的某个子串的最近位置。

    然后再扫一遍就行了。

    #include<bits/stdc++.h>
    using namespace std;
    char a[200],b[210000],c[110][110];
    int n,m,ans,next[101][101],first[51][200001],last[200001],v,gs[101];
    int main()
    {
        scanf("%s%s",a+1,b+1);
        n=strlen(a+1);m=strlen(b+1);
        for(int i=1;i<=n;i++)
        {
            while(a[i]=='*')
            i++;
            gs[0]++;
            while(a[i]!='*'&&i<=n)
            {
                c[gs[0]][++gs[gs[0]]]=a[i];
                i++;
            }
        }
        if(gs[0]==1&&n!=m)
        {
            cout<<'0'<<endl;
            return 0;
        }
        for(int i=1;i<m;i++)
            b[i+m]=b[i];
        for(int i=1;i<=gs[0];i++)
        {
            int k=0;
            for(int j=2;j<=gs[i];j++)
            {
                while(c[i][j]!=c[i][k+1]&&k)k=next[i][k];
                if(c[i][j]==c[i][k+1])k++;
                next[i][j]=k;
            }
        }
        for(int i=1;i<=gs[0];i++)
        {
            int k=0;
            for(int j=1;j<=2*m;j++)
            {
                while(k&&c[i][k+1]!=b[j])k=next[i][k];
                if(c[i][k+1]==b[j])k++;
                if(i==gs[0])last[j]=k;
                if(k==gs[i]){
                    int l=j-k+1;
                    while(l&&!first[i][l])
                    {
                        first[i][l]=j;
                        l--;
                    }
                    k=next[i][k];
                }
            }
        }
        for(int i=1;i<=m;i++)
        {
            int r=i+m-1,l=i-1,g=1;
            if(a[1]!='*'&&i+gs[g]-1!=first[g][i])continue;
            while(l<=r&&g<=gs[0])
            {
                l++;
                l=first[g][l];
                if(!l)break;
                g++;
            }
            if(a[n]!='*')
            {
                if(g!=gs[0]+1||l>r)continue;
                ans+=(last[r]==gs[gs[0]]);
            }
            else if(g==gs[0]+1&&l<=r)ans++;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    完。

    updata:

    之前的那个会被hack掉!

    *a

    aaaaaa

    会输出0

    在判无解的时候出锅了!

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    char a[200],b[210000],c[110][110];
    int n,m,ans,nex[110][110],first[55][210000],last[210000],v,gs[110];
    int main()
    {
    //    freopen("pattern.in","r",stdin);freopen("pattern.out","w",stdout);
        scanf("%s%s",a+1,b+1);
        n=strlen(a+1);m=strlen(b+1);
        for(int i=1;i<=n;i++)
        {
            while(a[i]=='*')
            i++;
            gs[0]++;
            while(a[i]!='*'&&i<=n)
            {
                c[gs[0]][++gs[gs[0]]]=a[i];
                i++;
            }
        }
        for(int i=1;i<m;i++)
            b[i+m]=b[i];
        for(int i=1;i<=gs[0];i++)
        {
            int k=0;
            for(int j=2;j<=gs[i];j++)
            {
                while(c[i][j]!=c[i][k+1]&&k)k=nex[i][k];
                if(c[i][j]==c[i][k+1])k++;
                nex[i][j]=k;
            }
        }
        for(int i=1;i<=gs[0];i++)
        {
            int k=0;
            for(int j=1;j<=2*m;j++)
            {
                while(k&&c[i][k+1]!=b[j])k=nex[i][k];
                if(c[i][k+1]==b[j])k++;
                if(i==gs[0])last[j]=k;
                if(k==gs[i]){
                    int l=j-k+1;
                    while(l&&!first[i][l])
                    {
                        first[i][l]=j;
                        l--;
                    }
                    k=nex[i][k];
                }
            }
        }
        int fl=0;
        for(int i=1;i<=n;i++)
        if(a[i]=='*'){
            fl=1;break;}
        if(!fl&&n!=m)
        {
            cout<<0<<endl;
            return 0;
        }
        for(int i=1;i<=m;i++)
        {
            int r=i+m-1,l=i-1,g=1;
            if(a[1]!='*'&&i+gs[g]-1!=first[g][i])continue;
            while(l<=r&&g<=gs[0])
            {
                l++;
                l=first[g][l];
                if(!l)break;
                g++;
            }
            if(a[n]!='*')
            {
                if(g!=gs[0]+1||l>r)continue;
                ans+=(last[r]==gs[gs[0]]);
            }
            else if(g==gs[0]+1&&l<=r)ans++;
        }
        cout<<ans<<endl;
        return 0;
    }
    View Code

    2019.8.19

  • 相关阅读:
    ElasticSearch入门到筋痛
    JavaScript学习(四)
    JavaScript学习(三)
    JavaScript学习(二)
    JavaWeb学习(一)
    final
    static
    object的方法
    java 数据类型
    spring mvc
  • 原文地址:https://www.cnblogs.com/Frost-Delay/p/day18.html
Copyright © 2020-2023  润新知