A:https://codeforces.com/contest/1221/problem/A

题意:

给出n个数字,问你是否能组成2048,和2048小游戏一摸一样

题解:

前缀和

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int q,n;
ll a[105],pre[105],x;
int main()
{
    scanf("%d",&q);
    while(q--)
    {
        int cnt = 0,flag = 0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            pre[i] = 0;
            scanf("%lld",&x);
            if(x <= 2048){
                a[++cnt] = x;
            }
        }
        sort(a+1,a+1+cnt);
        for(int i=1;i<=cnt;i++){
            pre[i] += (pre[i-1]+a[i]);
        }
        for(int i=cnt;i>=1;i--){
            for(int j=i-1;j>=0;j--)
            {
                if(pre[i] - pre[j] == 2048){
                    flag = 1;
                }
            }
        }
        if(flag)
            cout<<"YES"<<endl;
        else
            cout<<"NO"<<endl;
    }
    return 0;
}

B:https://codeforces.com/contest/1221/problem/B

题意:

构造题,在n*n的棋盘上,每个位置可以放白棋或者黑棋,最大化之间的斗争值,
即(x1,y1)和(x2,y2)满足棋的颜色不同且|x1−x2|=2 and |y1−y2|=1 或者 |x1−x2|=1 and |y1−y2|=2,俩个棋就会产生斗争

题解:

当你写出来3和4的棋盘,你就得出答案来了

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int a[110][110];
int main()
{
    int n;
    scanf("%d",&n);
    int now = 1;
    for(int i=1;i<=n;i++){
        a[i][1] = 1^now;
        now ^= 1;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=2;j<=n;j++)
        {
            if(a[i][j-1])
                a[i][j] = 0;
            else
                a[i][j] = 1;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(a[i][j])
                cout<<"W";
            else
                cout<<"B";
        }
        cout<<endl;
    }
    return 0;
}

C:https://codeforces.com/contest/1221/problem/C

题意:

给出a,b,c,三种职位的人数。每个组都必须要有a和b这俩种不同职位的人,c为无职业者,问你最多能有多少组

题解:

分类讨论

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll c, m,x;
        scanf("%lld%lld%lld",&c,&m,&x);
        if(c == 0 || m == 0){
            cout<<"0"<<endl;
            continue ;
        }
        ll minn = min(c,min(m,x));
        if(minn == c || minn == m){
            cout<<minn<<endl;
            continue ;
        }
        c -= x,m -= x;
        cout<<minn + min((c+m)/3,min(c,m))<<endl;
    }
    return 0;
}

D:https://codeforces.com/contest/1221/problem/D

题意:

给出n块木板的高度和每块木板升高一米的代价,要求任意俩块相邻的木板的高度不能相同最小的代价

题解:

dp,我们能发现,每块木板最多可以升高2m,升高再多都是没有意义的,只会使得代价更大

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxx = 300005;
ll a[maxx],b[maxx],dp[maxx][4];
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld%lld",&a[i],&b[i]);
        }
        dp[1][0] = 0ll;
        dp[1][1] = b[1];
        dp[1][2] = 2ll*b[1];
        for(int i=2;i<=n;i++)
        {
            if(a[i-1] == a[i]){
                dp[i][0] =  min(dp[i-1][1] , dp[i-1][2]);
                dp[i][1] = b[i] + min(dp[i-1][0] , dp[i-1][2]);
                dp[i][2] = 2ll*b[i] + min(dp[i-1][0] , dp[i-1][1]);
            }
            else if(a[i-1] + 1ll == a[i]){
                dp[i][0] = min(dp[i-1][0] , dp[i-1][2]);
                dp[i][1] = b[i] + min(dp[i-1][0] , dp[i-1][1]);
                dp[i][2] = 2ll*b[i] + min(dp[i-1][0],min(dp[i-1][1] , dp[i-1][2]));
            }
            else if(a[i-1] + 2ll == a[i]){
                dp[i][0] = min(dp[i-1][0] , dp[i-1][1]);
                dp[i][1] = b[i] + min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
                dp[i][2] = 2ll*b[i] + min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
            }
            else if(a[i-1] - 2ll == a[i]){
                dp[i][0] = min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
                dp[i][1] = b[i] + min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
                dp[i][2] = 2ll*b[i] + min(dp[i-1][1] , dp[i-1][2]);
            }
            else if(a[i-1] - 1ll == a[i]){
                dp[i][0] = min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
                dp[i][1] = b[i] + min(dp[i-1][1] , dp[i-1][2]);
                dp[i][2] = 2ll*b[i] + min(dp[i-1][0] , dp[i-1][2]);
            }
            else{
                dp[i][0] = min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
                dp[i][1] = b[i]+min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
                dp[i][2] = 2ll*b[i]+min(dp[i-1][0] , min(dp[i-1][1] , dp[i-1][2]));
            }
        }
        cout<<min(dp[n][0],min(dp[n][1],dp[n][2]))<<endl;
    }
    return 0;
}