- E表示有E道题目难度为Easy。
- EM表示有EM道题目难度可以为Easy或Medium。
- M表示有M道题目难度为Medium。
- MH表示有MH道题目难度可以为Medium或Hard。
- H表示有H道题目难度为Hard。
一行五个整数E,EM,M,MH,H。0 <= E+EM+M+MH+H <= 1018
一行一个数字表示答案
2 2 1 2 2
3
三组分别是E + EM + HE + MH + H
EM + M + MH
def find(i, E, EM, M, MH, H): # 容易题不够,从EM中搬 if E < i: # 容易题的剩余数量比场数小 cur = min(i - E, EM) E += cur EM -= cur # 难题不够,从MH中搬 if H < i: # 难题的剩余数量比场数小 cur = min(i - H, MH) H += cur MH -= cur # 模拟赛数量还可以往多了办(由于EM和MH分别被搬到E和H了,所以算作中等题) if M + EM + MH >= i and E >= i and H >= i: # 如果容易题、中等题、难题都够了,那就还可以办更多的比赛 return True return False if __name__ == "__main__": [E, EM, M, MH, H] = list(map(int, input().split())) max_val = (E + EM + M + MH + H) // 3 # 每场模拟赛三道题,此时为模拟赛场数的上限 res = 0 left, right = 0, max_val # 通过二分法来判断能否满足出题要求 while left <= right: mid = (left + right) // 2 if find(mid, E, EM, M, MH, H): left = mid + 1 res = max(res, mid) else: # 场数太多,收缩右边界 right = mid - 1 print(res)顺便想吐槽一下这套试卷,怎么一点击第三题就会自动交卷,被坑了好多次,第三题有bug
e,em,m,mh,h=map(int,input().split()) opt=(e+em+m+mh+h)//3 # 一开始用int((e+em+m+mh+h)/3),结果浮点精度爆炸,惨 ae,ah=e+em,h+mh # 先全分配给E和H if m>=opt: # 必补不齐 print(min(ae,ah,m)) exit() e2=max(0,min(em,ae-opt)) # E能提供的数目 h2=max(0,min(mh,ah-opt)) # H能提供的数目 print(min(ae-e2,ah-h2,m+e2+h2)) # 补齐后取最少的是我想简单了还是用例出简单了,我还以为是模拟题,为啥题解们都在二分查找
#include <iostream> #include <algorithm> using namespace std; int main() { long long E, EM, M, MH, H; cin >> E >> EM >> M >> MH >> H; long long upper = min({E + EM, EM + M + MH, MH + H}); long long avg = (E + EM + M + MH + H) / 3; auto res = min(upper, avg); res = min(res, (E+EM+M+MH) / 2); res = min(res, (EM+M+MH+H) / 2); cout << res; return 0; }
#include <iostream> using namespace std; int main() { unsigned long long E, EM, M, MH, H, E0, H0, D; cin >> E >> EM >> M >> MH >> H; // E0是E+EM的和,H0是MH+H的和,即最开始将EM看作E,将MH看作H E0 = E + EM; H0 = MH + H; // 分类讨论 if (M > E0 || M > H0) { // M最高 cout << min(E0, H0); } else if (E0 < H) { // E0<H也就是说,可以把所有MH都视为M cout << min(E0, M + MH); } else if (H0 < E) { // 同上 cout << min(H0, EM + M); } else { // 看E0和H0哪个更大,将它的上半部分截取加入到M // 并且修改E0或H0、EM或MH、M的大小 if (E0 <= H0) { D = H0 - E0; H0 -= D; MH -= D; M += D; } else { D = E0 - H0; E0 -= D; EM -= D; M += D; } // 此时E0和H0是等高的 if (M > E0) { // 如果M最高,那么直接输出E0即可 cout << E0; } else { // 否则计算需要从E0和H0拿多少填补到M // 注意(E0-M)/3是不对的,需要用到ceil除法 D = (E0 - M + 2) / 3; D = min(EM, D); D = min(D, MH); E0 -= D; H0 -= D; M = M + 2 * D; D = min(E0, M); D = min(D, H0); cout << D; } } }
#include<iostream> #include<stdio.h> #include<vector> using namespace std; typedef long long int llint; bool judge(vector<llint> T, llint k) { llint t; for(int i=0;i<5;i+=2) { t=T[i]+(i>0?T[i-1]:0); if(t<k) { if(i<4 && T[i+1]+t>=k) { T[i+1]-=k-t; } else return false; } } return true; } llint search(vector<llint>& T, llint min, llint max) { if(min==max) return min; if(min==max-1) return judge(T, max)?max:min; llint mid = min + (max-min)/2; if(judge(T, mid)) return search(T, mid, max); else return search(T, min, mid-1); } int main() { vector<llint> T(5); llint min,max; for(int i=0;i<5;i++) cin>>T[i]; min = T[0]; max = T[0]+T[1]; for(int i=1;i<5;i+=2) { if(T[i]<min) min=T[i]; llint t = T[i] + (i>0?T[i-1]:0) + (i<4?T[i+1]:0); if(t>max) max=t; } cout<<search(T,min,max)<<endl; return 0; }