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*(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\n",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\n",L*L*L);
    return 0;
}
C.cpp

D - Banned K

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

数据范围:$3 \leq N \leq 2 \times 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\n",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,1\leq W \leq 1000,1 \leq K \leq H \times 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\n",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\n",ans);
    return 0;
}
F.cpp

 

posted @ 2020-03-23 12:27  zdragon  阅读(312)  评论(0编辑  收藏  举报