2023 年上海市大学生程序设计竞赛 - 五月赛A,B,C
A. 选择
多造几组数据可以发现
\(dp[n] = dp[n / 2] + 1\).
假如一个序列为\(\{1,2,\cdots,n\}\),那我们从\(n/2\)后都减去\(n/2\),序列就变为了\(\{1,2,\cdots,n/2,1,2,\cdots,n/2\}\),那么我们只需要\(n/2\)时次数最少得方案即可.
#include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <queue> #include <set> #include <map> #include <cmath> #include <stack> #include <numeric> #define inf 0x3f3f3f3f #define yes cout << "YES" << endl #define no cout << "NO" << endl #define endl '\n' #define int long long using namespace std; const int N = 1e6 + 10, mod = 1e9 + 7; typedef unsigned long long ll; typedef pair<int,int> PII; void solve(){ cin >> n; vector<int> dp(n + 1); dp[1] = 1; for(int i = 1;i <= n;i ++) dp[i] = dp[i / 2] + 1; cout << dp[n] << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int Ke_scholar = 1; // cin >> Ke_scholar; while(Ke_scholar--) solve(); return 0; } /* */
B. 锐评
假设答案至少为 \(r\),且 \(a,b\) 已经完成操作,那么我们可以有这样的不等式:
\(\frac {a} {a + b} \geq r \Rightarrow (1 - r) a - rb \geq 0.\)
因此,给 \(a\) 加 1,\(b\) 减 1 的收益是线性的,因此一定在 \(a\) 最大和 \(b\) 最小时取到极值,对两者取 \(max\) 即可。
对\(b\)取最小时,记得把多出来的钱刷好评(另外如果你一直过不了第一个点的话,可以试试把\(scanf\)换成\(cin\),很奇怪\(\cdots\))
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define endl '\n' #define int long long using namespace std; int n,t,k,m; void solve() { int x,a,b; cin >> m >> x >> a >> b; int ma = a + m, mi = max(b - m / x,0ll); double ans = max((double) ma / (ma + b), (double)(a + m % x) / (m % x + a + mi)); printf("%.9lf\n",ans); } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int Ke_scholar = 1; cin >> Ke_scholar; while(Ke_scholar--) solve(); return 0; }
C. 饮茶
先假设每天都出去玩。这样,如果到某天来不及了,我只能放弃之前某天出去玩,此时显然放弃浪费时间越多的越好。因此,从前到后维护当前还能放弃的时间差最大堆,需要的时候弹掉最大的直到满足条件,最后输出堆的大小。
这里我用的是优先队列,不过都是一个道理
#include <bits/stdc++.h> #define endl '\n' #define int long long #define inf 0x3f3f3f3f using namespace std; const int N = 2e3 + 10; typedef pair<int,int> PII; map<int, int > mp; int n,m,t,k,c; int mod,ans; void solve() { cin >> n; priority_queue<int> T; int a,b; int ans = n; int sumtime = 0; for(int i = 0;i < n;i++){ cin >> t >> a >> b; if(a > b) T.push(a - b); sumtime += b - t; while(sumtime < 0){ if(T.empty()){ cout << -1 << endl; return ; } sumtime += T.top(); T.pop(); ans --; } } cout << ans << endl; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int Ke_scholar = 1; //cin >> Ke_scholar; while(Ke_scholar--) solve(); return 0; }
本文作者:Ke_scholar
本文链接:https://www.cnblogs.com/Kescholar/p/17506710.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步