原题链接:蓝桥杯2022年第十三届决赛真题-卡牌
解题思路:
思路1:暴力枚举
先把数组从小到大排序,然后先从小的开始凑套。
思路2:二分枚举
二分枚举可以凑成mid套
注意事项:
需要开longlong
参考代码:
暴力枚举:
#include <bits/stdc++.h> #define pii pair<int, int> #define x first #define y second #define ll long long using namespace std; const int N = 2e5 + 10; ll n, m; ll a[N], b[N]; //暴力 int main() { cin >> n >> m; for(int i = 0; i < n; i++)cin >> a[i]; ll mi = 1e18; for(int i = 0; i < n; i++){ cin >> b[i]; mi = min(b[i] + a[i], mi); // 最少能合成的套数 } sort(a, a + n);//从小到大排序 ll res = 0; for(int i = 0; i < n; i++){ int j = i+1; while(j < n && a[j] == a[i]){//牌号一样的 j++; } if(i == 0)res = a[i];//最少已经有的套数 else{ // cout << m << ' ' << res << ' ' << j << '\n'; if(m - (a[i] - a[i-1]) * (ll)i >= 0){//该号数前所有牌号都增加到当前牌号的套数 m -= (a[i] - a[i-1]) * (ll)i; res += (a[i] - a[i-1]); }else{ res += m / i; // 没有这么多牌 m = 0; break; } } i = j - 1; } // cout << res << ' ' << m << ' ' << n << '\n'; res += m / n;//剩下的牌 cout << min(mi, res); return 0; }
二分枚举:
#include <bits/stdc++.h> #define pii pair<int, int> #define x first #define y second #define ll long long using namespace std; const int N = 2e5 + 10; ll n, m; ll a[N], b[N]; //二分 bool check(ll mid){ ll add = 0; for(int i = 0; i < n; i++){ if(mid > a[i] && mid - a[i] > b[i]){ return false; } if(mid > a[i])add += mid - a[i]; if(add > m)return false; } return true; } int main(){ cin >> n >> m; ll mi = 1e18;//最少已经能凑成mi套 for(int i = 0; i < n; i++){ cin >> a[i]; mi = min(mi, a[i]); } for(int j = 0; j < n; j++)cin >> b[j]; ll l = mi, r = 1e18, mid, res; while(l <= r){ mid = l + r >> 1; // cout << l << ' ' << r << ' ' << mid << '\n'; if(check(mid)){ l = mid + 1; }else{ r = mid - 1; } } cout << l - 1 << '\n'; return 0; }
0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复