• AtCoder Beginner Contest 159


    传送门

    A - The Number of Even Pairs

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main() {
        //freopen("in.txt","r",stdin);
        int n,m;
        scanf("%d%d",&n,&m);
        printf("%d
    ",n*(n-1)/2+m*(m-1)/2);
        return 0;
    }
    A.cpp

    B - String Palindrome

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    char s[105];
    bool cal(int l,int r) {
        for(int i=l;i<=r;i++) {
            if(s[i]!=s[r+l-i]) return false;
        }
        return true;
    }
    int main() {
        //freopen("in.txt","r",stdin);
        scanf("%s",s+1);
        int n=strlen(s+1);
        bool f=true;
        if(!cal(1,n)) f=false;
        if(!cal(1,(n-1)/2)) f=false;
        if(!cal((n+3)/2,n)) f=false;
        printf("%s
    ",f?"Yes":"No");
        return 0;
    }
    B.cpp

    C - Maximum Volume

    题意:已知长方体的长+宽+高等于L,求长方体的最大体积。

    数据范围:$1 leq L leq 1000$

    题解:长方体最大体积时,长=宽=高=L/3。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    int main() {
        //freopen("in.txt","r",stdin);
        double L;
        scanf("%lf",&L),L/=3;
        printf("%.12f
    ",L*L*L);
        return 0;
    }
    C.cpp

    D - Banned K

    题意:给N个球,每个球上有数字Ai,求去掉第i个球以后,选两个相同数字的球的方案数。

    数据范围:$3 leq N leq 2 imes 10^{5},1 leq A_{i} leq N$

    题解:先算出不去掉任何球的方案数,即为每个数字个数中取两个的组合数总和。

    去掉第i个球,先减去该球上sum[Ai]对答案的贡献,然后加上C(sum[Ai]-1,2)。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=2e5+5;
    int a[N],num[N];
    int main() {
        //freopen("in.txt","r",stdin);
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
            num[a[i]]++;
        }
        ll ans=0;
        for(int i=1;i<=n;i++) {
            ans+=1LL*num[i]*(num[i]-1)/2;
        }
        for(int i=1;i<=n;i++) {
            ans-=1LL*num[a[i]]*(num[a[i]]-1)/2;
            num[a[i]]--;
            printf("%lld
    ",ans+1LL*num[a[i]]*(num[a[i]]-1)/2);
            num[a[i]]++;
            ans+=1LL*num[a[i]]*(num[a[i]]-1)/2;
        }
        return 0;
    }
    D.cpp

    E - Dividing Chocolate

    题意:给一个H*W的矩阵,其中’0‘代表该点为黑,’1‘代表该点为白,可以进行横着或竖着切,求至少切几次满足每块的白块不超过K块。

    数据范围:$1 leq H leq 10,1leq W leq 1000,1 leq K leq H imes W$

    题解:由于H很小,可以枚举横着切的情况,然后就是枚举每列求最小次数。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e3+5;
    char s[15][N];
    int a[15][N];
    int cal(int x1,int x2,int y) {
        int ans=0;
        for(int i=x1;i<=x2;i++) {
            ans+=(s[i][y]=='1');
        }
        return ans;
    }
    int main() {
        //freopen("in.txt","r",stdin);
        int n,m,k;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++) {
            scanf("%s",s[i]);
        }
        int ans=1e9;
        for(int s=0;s<(1<<(n-1));s++) {
            vector<int> vec;
            vec.push_back(-1);
            for(int i=0;i<n-1;i++) {
                if((1<<i)&s) vec.push_back(i);
            }
            vec.push_back(n-1);
            int sz=vec.size();
            bool f=true;
            for(int j=0;j<m;j++) {
                for(int i=1;i<sz;i++) {
                    a[i][j]=cal(vec[i-1]+1,vec[i],j);
                    if(a[i][j]>k) f=false;
                }   
            }
            if(!f) continue;
            int num=0,b[15]={0};
            for(int j=0;j<m;j++) {
                bool f=true;
                for(int i=1;i<sz;i++) {
                    b[i]+=a[i][j];
                    if(b[i]>k) f=false;
                }
                if(!f) {
                    num++;
                    for(int i=1;i<sz;i++) {
                        b[i]=a[i][j];
                    }
                }
            }
            ans=min(ans,sz-2+num);
        }
        printf("%d
    ",ans);
        return 0;
    }
    E.cpp

    F - Knapsack for All Segments

    题意:给一个长度为N的序列A,定义f(L,R)为AL~AR中子序列总和为S的方案数,求$sum_{L=1}^{N} sum_{R=L}^{N} f(L,R) $(对998244353取模)。

    数据范围:$1 leq N,S,A_{i} leq 3000$

    题解:通过朴素的01背包可以求出1~[1,N]的所有数,然后需要求2~[2,N]、3~[3,N]的总和,可以在第i个位置加一个起点,也就是f[0]++,这样就能合并在一起。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=3e3+5;
    const int MD=998244353;
    int a[N],f[N];
    void add(int &x,int y) {
        x+=y;
        if(x>=MD) x-=MD;
    }
    int main() {
        //freopen("in.txt","r",stdin);
        int n,s;
        scanf("%d%d",&n,&s);
        for(int i=0;i<n;i++) {
            scanf("%d",&a[i]);
        }
        int ans=0;
        for(int i=0;i<n;i++) {
            add(f[0],1);
            for(int j=s;j>=a[i];j--) {
                add(f[j],f[j-a[i]]);
            }
            add(ans,f[s]);
        }
        printf("%d
    ",ans);
        return 0;
    }
    F.cpp
  • 相关阅读:
    文件操作
    xadmin的使用
    Vue
    Redis
    Django
    python小结
    利用线程池和回调函数爬虫
    drf-基表、断关联表关系、级联删除、正方向查询、子序列化
    drf序列化
    drf初识
  • 原文地址:https://www.cnblogs.com/zdragon1104/p/12551440.html
Copyright © 2020-2023  润新知