【牛客训练记录】2025年浙江中医药大学程序设计竞赛(同步赛)

训练情况

赛后反思

C题犯蠢了,手玩几下就能猜出来的结论,结果自己想复杂了,以为是二分,D题又复现传智杯二分爆long long了,又没注意到,E题BFS搜索没记忆化MLE了

D题

传智杯二分爆long long重现,怒开__int128发现还是爆,只能边加边特判了,我们对于这题显然能观察到二分单调性,直接二分答案,判断最后利润是否 \(\ge m\)

点击查看代码
#include <bits/stdc++.h>
#define int __int128
#define endl '\n'

using namespace std;

const int N = 1e6 + 3;

int n,m;
int a[N];

inline int read(){
    int s = 0; char c = getchar();
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)) s = (s << 1) + (s << 3) + (c ^ 48),c = getchar();
    return s;
}

void print(int x){
    if(x>9) print(x/10);
    putchar(x%10+48);
}

bool pd(int x){
    int ans = 0;
    int now = x;
    for(int i = 2;i<=n;i++){
        if(a[i] > a[i-1]){
            int gx = (now/a[i-1]) * (a[i] - a[i-1]);
            ans += gx;
            if(ans >= m) return true;
            now += gx;
        }
    }
    return ans >= m;
}

void solve(){
    n = read(); m = read();
    for(int i = 1;i<=n;i++) a[i] = read();
    int l = 0,r = 1e18+1,m;
    while(l<r){
        m = l + r >> 1;
        if(pd(m)) r = m;
        else l = m + 1;
    }
    if(l == 1e18+1) cout<<"-1"<<endl;
    else print(l),puts("");
}

signed main(){
    // int T; cin>>T; while(T--)
    solve();
    return 0;
}

E题

BFS模板题,提前维护相同数字的位置,入队操作加入左右两边和相同的数字,记录到达终点的步数即可,这题需要记忆化一下,记录当前位置的最小步数,遇到记录过的就跳过,不然会重复入队 MLE。

点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define pii pair<int,int>
#define endl '\n'

using namespace std;

const int N = 1e6 + 3;

int n;
int a[N];
vector<int> v[N];
vector<int> d(N);

void bfs(int st){
    queue<pii> q;
    q.push({st,0});
    while(q.size()){
        int x = q.front().first;
        int step = q.front().second;
        q.pop();
        if(d[x]) continue;
        d[x] = step;
        if(x == n){
            cout<<step<<endl;
            exit(0);
        }
        if(x==1) q.push({x+1,step+1});
        else q.push({x-1,step+1}),q.push({x+1,step+1});
        for(auto i:v[a[x]]){
            if(i == x) continue;
            q.push({i,step+1});
        }
    }
}

void solve(){
    cin>>n;
    for(int i = 1;i<=n;i++) cin>>a[i],v[a[i]].emplace_back(i);
    bfs(1);
}

signed main(){
    // int T; cin>>T; while(T--)
    solve();
    return 0;
}

K题

签到题,直接记录连续的天数,累加答案即可

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'

using namespace std;

void solve(){
    int ans = 0;
    int n; cin>>n;
    int now = 0;
    for(int i = 1;i<=n;i++){
        int x; cin>>x;
        if(x == 1) now++;
        else now = 0;
        ans+=now;
    }
    cout<<ans<<endl;
}

signed main(){
    // int T; cin>>T; while(T--)
    solve();
    return 0;
}

L题

签到题加强版,我们直接维护映射记录对应人的连续天数,累加答案即可,还需要额外开一个变量记录谁当天没签过到,遇到隔天就连续天数全部清零,这题有个坑点,有人会一天内连续签到,注意特判一下即可

点击查看代码
#include <bits/stdc++.h>
// #define int long long
#define endl '\n'

using namespace std;

map<string,int> ans;
map<string,int> now;
map<string,bool> vis;

void solve(){
    int q; cin>>q;
    while(q--){
        int opt; cin>>opt;
        if(opt == 1){
            string s; cin>>s;
            if(vis[s]) continue;
            now[s]++;
            vis[s]=1;
            ans[s] += now[s];
        } else if(opt == 2){
            string s; cin>>s;
            cout<<ans[s]<<endl;
        } else if(opt == 3){
            for(auto i:now){
                if(!vis[i.first]) now[i.first] = 0;
            }
            vis.clear();
        }
    }
}

signed main(){
    // int T; cin>>T; while(T--)
    solve();
    return 0;
}
posted @ 2025-03-10 12:49  MNNUACM_2024ZY  阅读(78)  评论(0)    收藏  举报