zoukankan      html  css  js  c++  java
  • 牛客题集:练习赛69、70

    练习赛70

    A

    尺取即可

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e6+10;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    map<char ,int > mapp;
    string ss="puleyaknoi";
    char s[maxn];
    bool check(){
        for (int i = 0; i <= 9; ++i)
        {
            if (mapp[ss[i]]==0) return false; 
        }
        return true;
    }
    int t,n,l,r,ans;
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        t=read();
        while (t--)
        {
            scanf("%s",s+1);
            n=strlen(s+1);
            l=r=1;
            mapp.clear();
            mapp[s[1]]=1;
            ans=INF;
            while (r<=n)
            {
                if (check())
                {
                    ans=min(ans,r-l+1);
                    mapp[s[l]]--;
                    l++;
                }
                else
                {
                    r++;
                    mapp[s[r]]++;
                }
            }
            cout << (ans==INF?-1:ans) <<endl;
        }
        return 0;
    }
    View Code

    B

    因为题目的要求,字符串每个字母要按顺序出现,那我们只需找到一个字母,再从这个字母位置往后查找下一个字母,每次查找都用二分即可。

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e6+10;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    string ss="puleyaknoi";
    char s[maxn];
    int a[maxn][27],ans,n,t,l,r,mid,now,mao;
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        t=read();
        while (t--)
        {
            scanf("%s",s+1);
            n=strlen(s+1);
            for (int i = 1; i <= n; ++i)
            {
                for (int j = 1; j <= 26; ++j)
                {
                    a[i][j]=a[i-1][j];
                }    
                a[i][s[i]-'a'+1]++;
            }
            for (int j = 1; j <= 26; ++j) a[n+1][j]=a[n][j]+1;
            ans=INF;
            for (int i = 1; i <= n; ++i)
            {
                now = 0;
                if (s[i]=='p')
                {
                    l=i;
                    for (int j = 1; j <= 9; ++j)
                    {
                        r=n;
                        mao=l;
                        while (l<=r)
                        {
                            mid=(l+r)/2;
                            if (a[mid][ss[j]-'a'+1]>=a[mao][ss[j]-'a'+1]+1) r=mid-1;
                                else l=mid+1;
                        }
                        if (l==n+1) 
                        {
                            now=0;
                            break;
                        }
                        else now=max(now,l-i+1);
                    }
                    if (now!=0) ans= min(ans,now);
                }
            }
            cout << (ans==INF?-1:ans) <<endl;
        }
        return 0;
    }
    View Code

    D

    用个map记录每次增加的边,同时记录下每个点的出现次数,如果要删去一条边,map可以直接查询是否存在这条边,存在则判断点的出现次数,如果两个点都存在树中 ,说明删掉这条边还存在其他边把他们连起来,树的个数不变;如果两个点都只出现 1 次,说明两个点都只靠这条边连起来形成一颗树,删掉则树的个数 -1。如果要增添一条边,两条边都没出现过的话,树的个数 +1;都存在树中的话,说明两颗树会被合并成一颗树,树的个数 -1.

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<int, int> pii;
    const int maxn = 1e6+10;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    int du[maxn],t,op,u,v,id,x,y,ans;
    map<pii,int> mapp;
    map<int,int> vis;
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        t=read();
        while (t--)
        {
            op=read();
            if (op==1) 
            {
                u=read(),v=read();
                if (!mapp[{u,v}])
                {
                    mapp[{u,v}]=mapp[{v,u}]=1;
                    if (!vis[u]) vis[u]=++id;
                    if (!vis[v]) vis[v]=++id;
                    x=vis[u],y=vis[v];
                    if (du[x]==0 && du[y]==0) ans++;
                        else if (du[x] && du[y]) ans--;
                    du[x]++,du[y]++;
                }
            }else if (op==2)
            {
                u=read(),v=read();
                if (mapp[{u,v}])
                {
                    mapp[{u,v}]=mapp[{v,u}]=0;
                    x=vis[u],y=vis[v];
                    du[x]--,du[y]--;
                    if (du[x]==0 && du[y]==0) ans--;
                        else if (du[x] && du[y]) ans++;
                }
            }else
            {
                cout << ans <<endl;
            }
        }
        return 0;
    }
    View Code

    练习赛69

    B

    排个序,把最大的几个都挑出来,总能把这几个数分组

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e6+10;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    int n,a[maxn],x,y;
    ll sum[maxn],ans;
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        n=read();
        for (int i = 1; i <= n; ++i)
        {
            a[i]=read();
        }
        sort(a+1,a+1+n);
        reverse(a+1,a+1+n);
        for (int i = 1; i <= n; ++i)
        {
            sum[i]=sum[i-1]+a[i];
        }
        x=read(),y=read();
        for (int i = 1; i <= x; ++i)
        {
            for (int j = 1; j <= y; ++j)
            {
                ans+=sum[i*j];
            }
        }
        cout << ans <<endl;
        return 0;
    }
    View Code

    C

    对答案有贡献的边肯定是最大生成树上的边,因为这棵树是所有选出来的树当中权值总和最大的,那么可以将这些边先拉出来,每条边至少会被贡献一次。

    对于一条最大的边,我们要让它产生贡献,那么只能是这条边的两个点产生出来,之后这条边再也不会有所贡献了,同理其他的边,因此可以看出每条边只对答案贡献了一次。

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e6+10;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    struct node
    {
        int u,v,w;
        bool operator<(node& x) const 
        {
            return w>x.w;
        } 
    };
    vector<node> G;
    struct DSU{
        int a[maxn],sz[maxn];
        void init(int n){
            iota(a,a+n+1,0);
            fill(sz,sz+n+1,1);
        }
        int fa(int x){
            return a[x]==x?x:a[x]=fa(a[x]);
        }
        bool query(int x,int y){ //查找
            return fa(x)==fa(y);
        }
        void join(int x,int y){ //合并
            x=fa(x),y=fa(y);
            if(x==y)return;
            if(sz[x]>sz[y])swap(x,y);
            a[x]=y; sz[y]+=sz[x];
        }
        int operator[](int x){return fa(x);}
    }d;
    int n,m,u,v,w;
    ll ans;
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        n=read(),m=read();
        d.init(n);
        for (int i = 1; i <= m; ++i)
        {
            u=read(),v=read(),w=read();
            G.pb({u,v,w});
        }
        sort(G.begin(),G.end());
        for (auto x:G)
        {
            if (d.query(x.u,x.v)) continue;
            ans+=x.w;
            d.join(x.u,x.v);
        }
        cout << ans <<endl;
        return 0;
    }
    View Code

    D

    一个选手的分数 ai 加 d 会导致区间 (ai,ai+d)中的数必须都要+d

    那么一个选手就会牵连致其他选手,构成一个团体

    考虑分组背包,当前选手不加d,那么就要看前一位选手会不会牵连到他,当前选手加d,那么前一位选手加不加都无所谓。

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 5005;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 998244353;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    struct CC{
        static const int N=5005;
        ll fac[N],inv[N];
        CC(){
            fac[0]=1;
            for (int i = 1; i < N; ++i) fac[i]=fac[i-1]*i%mod;
            inv[N-1]=qpow(fac[N-1],mod-2);
            for (int i = N-1; i>= 1; --i) inv[i-1]=inv[i]*i%mod;
        }
        ll operator()(ll a,ll b){ //a>=b
            if(a<b || b<0)return 0;
            return fac[a]*inv[a-b]%mod*inv[b]%mod;
        }
        ll A(ll a,ll b){ //a>=b
            if(a<b || b<0)return 0;
            return fac[a]*inv[a-b]%mod;
        }
    }C;
    int n;
    int d,f[maxn][maxn][2],a[maxn];
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        n=read(),d=read();
        for (int i = 1; i <= n; ++i)
        {
            a[i]=read();
        }
        sort(a+1,a+1+n);
        f[1][0][0]=f[1][1][1]=1;
    
        for (int i = 2; i <= n; ++i)
        {
            for (int j = 0; j <= n; ++j)
            {
                f[i][j][0]=(f[i][j][0]+f[i-1][j][0])%mod;
                if(a[i-1]+d<=a[i])
                    f[i][j][0]=(f[i][j][0]+f[i-1][j][1])%mod;
                if (j+1 <= n)
                {
                    f[i][j+1][1]=(f[i][j+1][1]+f[i-1][j][0])%mod;
                    f[i][j+1][1]=(f[i][j+1][1]+f[i-1][j][1])%mod;
                }
            }
        }
        for (int i = 1; i <= n; ++i)
        {
            ll ans = f[n][i][0]+f[n][i][1];
            ans %= mod;
            cout << ans*qpow(C(n,i),mod-2)%mod <<endl;
        }
        return 0;
    }
    View Code

    E

    这题再次学到了……

    因为要选择一个区间,这个区间的涉及下标和元素要全部一样,所以他们异或起来的值都是一样的,但是为防止下标和元素不同,异或起来的值相同的情况,我们就给予它们一个哈希值,这样就可以完全避免冲突。

    #include <bits/stdc++.h>
    #define debug freopen("r.txt","r",stdin)
    #define mp make_pair
    #define ri register int
    #define pb push_back
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef double lf;
    typedef pair<ll, ll> pii;
    const int maxn = 1e6+10;
    const int N = 1500+10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int hash_num = 131;
    const double eps=1e-6;
    const double PI=acos(-1.0);
    inline ll read(){ll s=0,w=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;}
    // mt19937_64 rnd(time(0)); unsigned long long
    // mt19937 rnd(time(0)); unsigned int
    mt19937_64 rnd(time(0));
    ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
    int n;
    ll a[maxn],pre[maxn],ans,k[maxn];
    unordered_map<ll,int>mapp;
    int main()
    {
        #ifndef ONLINE_JUDGE
            debug;
        #endif
        n=read();
        for (int i = 1; i <= n; ++i)
        {
            a[i]=read();
            k[i]=rnd();
        }
        for (int i = 1; i <= n; ++i)
        {
            pre[i] = pre[i-1] ^ k[i] ^ k[a[i]];
        }
        mapp[0]=1;
        for (int i = 1; i <= n; ++i)
        {
            ans+=mapp[pre[i]];
            mapp[pre[i]]++;
        }
        cout << ans <<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    Java_static
    Java_字符串操作
    Java_==
    Java_字符串
    Java_Random
    Java_Scanner
    杨辉三角
    颜色分类
    字符串倒序
    jQuery的基本事件
  • 原文地址:https://www.cnblogs.com/Y-Knightqin/p/14418833.html
Copyright © 2011-2022 走看看