吐了,比赛开始时。报名报成小号了。这次的 比较简单,没有码量题,好评。

A

分析

读懂题意,模拟即可。

代码

//  sto xzc orz
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
    return f ? -x : x;
}
int main() {
    int T = read();
    while(T--) {
        int a = read(),b = read(),c = read(),d = read();
        int A = abs(a - c) + abs(b - d);
        int B = abs(a - c) + abs(d - 1);
        int C = abs(c - 1) + abs(b - d);
        int D = abs(c - 1) + abs(d - 1);
        printf("%d\n",max(max(A,B),max(C,D))); 
    }
}

B

分析

颜色数目比较少,直接枚举颜色种类,贪心选取。最后取最小值。

代码

#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
    return f ? -x : x;
}
const int N = 1e5 + 100,inf = 0x3f3f3f3f;
int col[N],n,k,b[N];
bool vis[110];
vector<int> C;
int main() {
    int T = read();
    while(T--) {
        memset(vis,0,sizeof(vis));C.clear();
        n = read();k = read();
        for(int i = 1;i <= n;i++) {
            col[i] = read();
            if(vis[col[i]] == 0) C.push_back(col[i]),vis[col[i]] = 1;
        }
        int ans = inf;
        for(auto p : C) {
            memcpy(b,col,sizeof(b));int sum = 0;
            for(int i = 1;i <= n;i++) {
                if(b[i] != p) {
                    sum++;i = i + k - 1;
                }
            }
            ans = min(ans,sum);
        }
        printf("%d\n",ans);
    }
}

C

分析

枚举删除多少个靠在前面的木板。枚举余数,从后到前枚举。

代码

//  sto xzc orz
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
ll read() {
    ll x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
    return f ? -x : x;
}
const ll N = 6e5 + 100,inf = 1e18;
ll a[N],b[N],A,B,n,ans,x,y,Tim = 0,cnt[N],dfn[N];
char ch[N];
signed main() {
    ll T = read();
    while(T--) {
        n = read();A = read();B = read();ans = inf;
        scanf("%s" ,ch+1);Tim++;
        x = read();y = read();
        for(int i = n;i >= A;i--) {
            ll now = (n - i) % B;
            if(dfn[now] != Tim) cnt[now] = 0,dfn[now] = Tim;
            cnt[now] += (ch[i]=='0');
            ans = min(ans,cnt[now]  * x + (i - A) * y);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

D

分析

比较好的一道题,个人感觉比 好。我们先分析如果有三个连续的数最高位相同,那么我们只需要对 个操作一次就好了,所以根据鸽巢原理。 时,可以直接输出 。那么当 时,我们仍有一个性质,我们操作的元素一定是一堆连续的元素,而且中间只会有一个断点。那么这个可以用异或前缀和维护。

代码

//  sto xzc orz
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
    return f ? -x : x;
}
const int N = 1e5 + 100;
int a[N],b[N],ans = 0x3f3f3f3f,n;
int main() {
    n = read();
    if(n >= 62) printf("1\n");
    else {
        for(int i = 1;i <= n;i++) a[i] = read();
        for(int i = 1;i <= n;i++) b[i] = a[i] ^ b[i - 1];
        for(int i = 1;i <= n;i++) {
            for(int j = 0;j < i;j++) {
                for(int k = i + 1;k <= n;k++) {
                    if((b[i] ^ b[j]) > (b[k] ^ b[i])) {
                        ans = min(ans,k - j - 2);
                    }
                }
            }
        }
        if(ans != 0x3f3f3f3f) cout << ans << endl;
        else cout << "-1" << endl;
    }
}

E

分析

我们可以贪心的选取,每次选取最大的元素来做。我们先把所有元素分成 组,那么我们每次取出最大的一组,加上贡献。用 维护一下就好了。

代码

#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define ll long long
int read() {
    int x = 0,f = 0;char ch = getchar();
    while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();}
    return f ? -x : x;
}
const int N = 5e5 + 100;
multiset<ll> s;
ll ans = 0;
ll n,a[N],k;
int main() {
    n = read();k = read();
    for(ll i = 1;i <= k + 1;i++) s.insert(0);
    for(ll i = 1;i <= n;i++) a[i] = read();
    sort(a + 1,a + 1 + n);
    for(ll i = n;i >= 1;i--) {
        ll x = *s.rbegin();s.erase(--s.end());
        ans += x;s.insert(x + a[i]);
    }cout << ans << endl;
    return 0;
}