想法题是硬伤,面对卡题和卡bug的情况应对能力太差

A.求两个前缀和以及两个后缀和,相邻最小值的最大值。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 codeforces-1138 (div2) 随笔 第1张
#include<iostream>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn];
int pre1[maxn],pre2[maxn],erp1[maxn],erp2[maxn];
int main(){
    int N; scanf("%d",&N);
    for(int i = 1; i <= N ; i ++){
        scanf("%d",&a[i]);
        if(a[i] == 1) pre1[i] = pre1[i - 1] + 1;
        else pre2[i] = pre2[i - 1] + 1;
    }
    for(int i = N; i >= 1; i --){
        if(a[i] == 1) erp1[i] = erp1[i + 1] + 1;
        else erp2[i] = erp2[i + 1] + 1;
    }
    int ans = 0;
    for(int i = 1; i <= N; i ++){
        ans = max(ans,min(pre1[i],erp2[i + 1]));
        ans = max(ans,min(pre2[i],erp1[i + 1]));
    }
    printf("%d",ans * 2);
    return 0;
} 
A

 

B.将人分为00,10,01,11四种,总人数已知为ABCD,假设我们需要选择的分别为abcd。

得到方程1.a + b + c + d =  n / 2 方程2 b + d = (C - c) + (D - d)

化简方程2得到b + c + 2d = C + D;

CD为已知常数,考虑暴力枚举dc,可推得b,根据方程1可推得a,然后check,时间复杂度O(n²)

codeforces-1138 (div2) 随笔 第3张
#include<iostream>
#include<vector>
#include<algorithm>
#define pb push_back
using namespace std;
const int maxn = 5000;
struct Node{
    int a,b;
    int id;
}node[maxn];
char str[maxn];
int Stack[maxn],top;
vector<int>ans;
bool cmp(Node a,Node b){
    return a.a + a.b > b.a + b.b;
}
vector<int>aa,ab,ba,bb;
int main(){
    int N; scanf("%d",&N);
    scanf("%s",str + 1);
    for(int i = 1; i <= N ; i ++){
        node[i].a = str[i] - '0';
        node[i].id = i;
    }
    scanf("%s",str + 1);
    for(int i = 1; i <= N ; i ++) node[i].b = str[i] - '0';
    for(int i = 1; i <= N ; i ++){
        if(node[i].a + node[i].b == 0) aa.pb(i);
        else if(node[i].a == 1 && node[i].b == 0) ba.pb(i);
        else if(node[i].a == 0 && node[i].b == 1) ab.pb(i);
        else bb.pb(i);
    }
    int A = aa.size(),B = ba.size(),C = ab.size(),D = bb.size();
    for(int d = 0; 2 * d <= C + D && d <= D; d++){
        for(int c = 0; c <= C && c + 2 * d <= C + D;c++){
            int b = (C - c) + (D - d) - d;
            if(b < 0 || b > B) continue;
            int a = (N / 2) - b - c - d;
            if(a < 0 || a > A) continue;
            for(int i = 0 ; i < a; i ++) printf("%d ",aa[i]);
            for(int i = 0 ; i < b; i ++) printf("%d ",ba[i]);
            for(int i = 0 ; i < c; i ++) printf("%d ",ab[i]);
            for(int i = 0 ; i < d; i ++) printf("%d ",bb[i]);
            return 0;
        }
    }
    puts("-1");
    return 0;
} 
B

 

C.对每行每列分别离散化,对于一个点的x是交叉点在横竖往前排名较后的位置 加上往后排名较前的位置。

codeforces-1138 (div2) 随笔 第5张
#include<iostream>
#include<vector>
#include<algorithm>
#define pb push_back
#define LL long long 
using namespace std;
const int maxn = 2010;
int N,M;
LL MAP[maxn][maxn];
LL sr[maxn][maxn],sc[maxn][maxn],hr[maxn][maxn],hc[maxn][maxn];
LL Hash[maxn];
int main(){
    scanf("%d%d",&N,&M);
    for(int i = 1; i <= N; i ++){
        for(int j = 1; j <= M ; j ++){
            scanf("%lld",&MAP[i][j]);
        }
    }
    for(int i = 1;i <= N ; i ++){
        for(int j = 1; j <= M; j ++) Hash[j] = MAP[i][j];
        sort(Hash + 1,Hash + 1 + M);
        int cnt = unique(Hash + 1,Hash + 1 + M) - Hash - 1;
        for(int j = 1; j <= M ; j ++){
            int t = lower_bound(Hash + 1,Hash + 1 + cnt,MAP[i][j]) - Hash;
            sc[i][j] = t; hc[i][j] = cnt - t;
        }
    }
    for(int j = 1; j <= M ; j ++){
        for(int i = 1; i <= N ; i ++) Hash[i] = MAP[i][j];
        sort(Hash + 1,Hash + 1 + N);
        int cnt = unique(Hash + 1,Hash + 1 + N) - Hash - 1;
        for(int i = 1; i <= N; i ++){
            int t = lower_bound(Hash + 1,Hash + 1 + cnt,MAP[i][j]) - Hash;
            sr[i][j] = t; hr[i][j] = cnt - t;
        }
    }
    for(int i = 1; i <= N; i ++){
        for(int j = 1; j <= M; j ++){
            if(j != 1) printf(" ");
            printf("%lld",max(sc[i][j],sr[i][j]) + max(hr[i][j],hc[i][j]));
        }
        puts("");
    }
    return 0;
} 
C

 

D.没看清楚题目意思为子串之间可以相互重叠,需要求出一个kmp的next数组,然后贪心的迭代最多能放下的数字。

codeforces-1138 (div2) 随笔 第7张
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
#define pb push_back
#define LL long long 
using namespace std;
const int maxn = 5e5 + 10;
int N,M;
char str1[maxn],str2[maxn];
int Z,O,z,o;
void get_next(char x[],int m,int nxt[]){
    int j = 0;
    nxt[1] = 0;
    for(int i = 2; i <= m ; i ++){
        while(j && x[i] != x[j + 1]) j = nxt[j];
        if(x[j + 1] == x[i]) j ++;
        nxt[i] = j;
    }
}
int Next[maxn];
int main(){
    Z = O = z = o = 0;
    scanf("%s%s",str1 + 1,str2 + 1);
    for(int i = 1;str1[i]; i ++){
        if(str1[i] == '0') Z++;
        else O++;
    }
    for(int i = 1;str2[i]; i ++){
        if(str2[i] == '0') z++;
        else o++;
    }
    if(z > Z || o > O){
        for(int i = 0 ; i < O; i ++) printf("1");
        for(int i = 0 ; i < Z; i ++) printf("0");
    }else{
        Z -= z; O -= o;
        int l = strlen(str2 + 1);
        get_next(str2,l,Next);
        o = z = 0;
        int ans = 1;
        for(int i = Next[l] + 1; i <= l ; i ++){
            if(str2[i] == '1') o++;
            else z++;
        }
        while(Z - z >= 0 && O - o >= 0){
            ans++;
            Z -= z; O -= o;
        }
        printf("%s",str2 + 1);
        for(int i = 1 ; i < ans; i ++){
            for(int j = Next[l] + 1; j <= l; j ++) printf("%c",str2[j]);
        } 
        for(int i = 0 ; i < O; i ++) printf("1");
        for(int i = 0 ; i < Z; i ++) printf("0");
    }
    return 0;
} 
D

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄