zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 167-A,B,C,D,E

    ABC-167-A,B,C,D,E

    打卡8/6 感觉最近的想法题反应太慢了,打几把ABC压压惊,下回争取开到E

    A - Registration

    题意:

    给你两个字符串s,t,问你t是不是只比s多最后一个字母

    思路:

    可以通过给s填一个字母或给t删掉最后一个字母来比较

    签到题拼手速

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a) & -(a))
    #define clean(a, b) memset(a, b, sizeof(a))
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e5 + 9;
    
    int _;
    
    //========================================================================
    
    //========================================================================
    int main()
    {
        string a,b;
        cin>>a>>b;
        int len=b.size();
        a+=b[len-1];
        if(a==b)puts("Yes");
        else puts("No");
        return 0;
    }
    
    

    B - Easy Linear Programming

    题意:

    给你A,B,C,K,分别代表你有A个1,B个0,C个-1,想取K个数,取到的最大权值是多少?

    思路:

    贪心的想自然是优先取A然后B,C

    手速题

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a) & -(a))
    #define clean(a, b) memset(a, b, sizeof(a))
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e5 + 9;
    
    int _;
    
    //========================================================================
    int a[5];
    //========================================================================
    int main()
    {
        for(int i=1;i<=3;i++)
        {
            scanf("%d",&a[i]);
        }
        int k,ans=0;
        scanf("%d",&k);
    
        if(a[1]>k) ans+=k,k=0;
        else ans+=a[1],k-=a[1];
    
        if(a[2]>k) k=0;
        else k-=a[2];
    
        if(a[3]>k) ans-=k,k=0;
        else ans-=a[3],k-=a[3];
    
        printf("%d
    ",ans);
        return 0;
    }
    
    

    C - Skill Up

    题意:

    书店有n本书,每本书都讲了m种算法,学会了这个算法,对他的理解就增加a[i][j],每本书都有自己的价钱,问至少买哪几本书,能使花费最小,但对每个算法的理解都达到了x

    思路:

    我就是最后这里没有念懂题QAQ
    n,m很小,可以枚举,官方题解是dfs,状压枚举也可以,对于每一本书,都有选和不选两种选择,所以可以用二进制的 ( ( 1 << n ) - 1 ) 来表示所有情况,暴力就可以了

    我发誓以后的easy题我指定先考虑暴力

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a) & -(a))
    #define clean(a, b) memset(a, b, sizeof(a))
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int maxn = 2e5 + 9;
    
    int _;
    
    //========================================================================
    int a[20][20],ans[20],c[20];
    //========================================================================
    int main()
    {
        int n,m,x;
        scanf("%d%d%d",&n,&m,&x);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&c[i]);
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&a[i][j]);
            }
        }
        int base=(1<<n),minn=inf;
        for(int i=1;i<base;i++)
        {
            clean(ans,0);
            int val=0;
            for(int j=0;j<n;j++)
            {
                if(((i>>j)&1)==1) 
                {
                    val+=c[j+1];
                    for(int k=1;k<=m;k++)
                    {
                        ans[k]+=a[j+1][k];
                    }
                }
            }
            int flag=0;
            for(int k=1;k<=m;k++)
            {
                if(ans[k]<x) flag++; 
            }
            if(flag==0) minn=min(minn,val);
        }
        if(minn==inf) minn=-1;
        printf("%d
    ",minn);
        return 0;
    }
    
    

    D - Teleporter

    题意:

    有n个城市,每个城市都指向一个城市,从1开始,你想走k个地方,问走完这k个地方到达的是第几个城市

    思路:

    k 1e18,模拟就不要想了嗷,因为一共就n个城市,所以你走完这n个城市后就一定是循环的了,找到前缀为x,循环结为y,用b数组把路径上的城市记下来,mod=(k-x)%y,如果mod==0,证明是循环的最后一位,ans=b[y+x],否则,ans=b[mod+x];哦对,还要判断一下是不是还没开始循环就到地方了,如果是,直接输出即可

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a) & -(a))
    #define clean(a, b) memset(a, b, sizeof(a))
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    const int maxn = 2e5 + 9;
    
    int _;
    
    //========================================================================
    int a[maxn],vis[maxn],b[maxn];
    //========================================================================
    int main()
    {
        int n;
        ll k;
        scanf("%d%lld",&n,&k);
        k++;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int pos=1,x,y,ans_;
        vis[1]=1;
        b[1]=1;
        for(int i=2;i<=n+1;i++)//要跑到n+1因为想要到达所有的城市回到1 就是n+1
        {
            pos=a[pos];
            b[i]=pos;
            if(vis[pos])
            {
                x=vis[pos]-1;
                y=i-vis[pos];
                break;
            }
            vis[pos]=i;
        }
        if(k>=(x+y))
        {
            int ans=(k-x)%y;
            if(ans==0) ans=b[y+x];
            else ans=b[ans+x];
            printf("%d
    ",ans);
        }
        else 
        {
            printf("%d
    ",b[k]);
        }
        return 0;
    }
    /*
    6 5
    3 6 5 4 2 1
    */
    
    

    E - Colorful Blocks

    题意:

    (1-m)中选(n)个数排列,要求最多只有(k)组两个一样的连在一起,问不一样的排列有多少种??

    思路:

    我排列组合怕是白学了,没想到,主要是还没太整明白,看了题解才知道dp的思路也能做(实现不了),dp[选了i个数][有j组一样的连在一起],(dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*(m-1)) 增加了连在一起的组数的话,那他的颜色就是固定的,就是1,每增加就是(m-1)有一种不能选

    然后就可以经过一系列的推导 得出结论(其实把这个数组展开 巴拉巴拉 加一下)

    当然(dp)的思路清楚了的话,组合数学也就不难理解了,设有(j)个位置的相邻是相同的,一共(n-1)个位置(他占的是两个数中间的缝)就是(C_{n-1}^{j}),然后有(m)个数字,就是(m*C_{n-1}^{j}),再看剩下的位子,(j)个位置相邻,有(j+1)个位置已经被占上了,剩下((n-1-j))个,每个位置都可以选((m-1))个数,就是((m-1)^{n-i-j})乘到一起,(ans=m*C_{n-1}^{j}*(m-1)^{n-i-j}).

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lowbit(a) ((a) & -(a))
    #define clean(a, b) memset(a, b, sizeof(a))
    const int mod = 998244353;
    const int inf = 0x3f3f3f3f;
    const int maxn = 2e5 + 9;
    
    int _;
    
    //========================================================================
    ll pr[maxn];
    void init()
    {
      pr[0]=1;
      for(int i=1;i<=maxn;i++)
        {
            pr[i]=pr[i-1]*i%mod;
        }
    }
    ll fpow(ll a,ll b)
    {
        a%=mod;
        ll ans=1;
        while(b)
        {
            if(b&1) ans=ans*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return ans%mod;
    }
    ll c(ll a,ll b)
    {
        if (a < b || a < 0 || b < 0) return 0;
        return pr[a]*fpow(pr[b]*pr[a-b]%mod,mod-2)%mod;
    }
    //========================================================================
    int main()
    {
        init();
        int n,m,k,ans=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<=k;i++)
        {
            ans=(ans+(m*c(n-1,i)%mod)*fpow(m-1,n-1-i)%mod)%mod;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    CodeForces gym Nasta Rabbara lct
    bzoj 4025 二分图 lct
    CodeForces 785E Anton and Permutation
    bzoj 3669 魔法森林
    模板汇总——快读 fread
    bzoj2049 Cave 洞穴勘测 lct
    bzoj 2002 弹飞绵羊 lct裸题
    HDU 6394 Tree 分块 || lct
    HDU 6364 Ringland
    nyoj221_Tree_subsequent_traversal
  • 原文地址:https://www.cnblogs.com/YangKun-/p/13068358.html
Copyright © 2011-2022 走看看