【牛客训练记录】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;
}

浙公网安备 33010602011771号