【题目描述】
GDOI2016 将于 4 月 30 日至 5 月 3 日在四会中学举行,为了准备这次比赛,评委们正忙着出题。题目难度分为“简单题”、“中等题”、“难题”三个等级。评委们已经出好了 E 道简单题, M 道中等题, H 道难题。然后评委们又出了 EM道“简中”题和 MH 道“中难”题。所谓的“简中题”是指该类型的题既可以归类为“简单题”也可以归类为“中等题”。所谓的“中难题”是指该类型的题既可以归类为“中等题”也可以归类为“难题”。评委们规定:一场比赛必须包含 3 道题,其中 1 题是“简单题”, 1 题是“中等题”, 1 题是“难题”。每道题目至多只能出现在一场比赛中。问题是:评委们最多可以组织多少场比赛?
【输入格式】 pro.in
多组测试数据。
第一行,一个整数 R,表示有 R 组测试数据。
每组测试数据格式如下:
一行, 5 个整数: E、 EM、 M、 MH、 H。 0 <= E、 EM、 M、 MH、 H<=100000。
【输出格式】 pro.out
共 R 行,每行一个整数。
#include <fstream>
using namespace std;
ifstream fin("pro.in");
ofstream fout("pro.out");
bool check(int, int, int, int, int, int);
int main() {
int R;
fin>>R;
for (int i=0; i<R; i++) {
int E, EM, M, MH, H, Ans = 0;
fin>>E>>EM>>M>>MH>>H;
int l = 0, r = 166667; //比赛数
while (l+1 < r) {
int mid = (l+r) / 2;
if (check(E, EM, M, MH, H, mid))
l = mid;
else
r = mid;
}
fout<<l<<endl;
}
return 0;
}
bool check(int e, int em, int m, int mh, int h, int mid) {
if (e >= mid) { //e满足mid
m += em, em = 0; //把em全部分给m
if (m >= mid) { //m满足mid
h += mh, mh = 0; //把mh全部分给h
return (h >= mid)?true:false;//h满足mid
} else { //m不满足mid
int p = mid - m; //m与mid差多少
if (mh >= p) { //若mh满足p
m = mid, mh -= p; //用mh填补m
h += mh, mh = 0; //把剩下的mh分给h
return (h >= mid)?true:false;//h满足mid
} else { //mh不满足p
return false;
}
}
} else { //e不满足mid
int p = mid - e; //e与mid差多少
if (em >= p) { //若em满足p
e = mid, em -= p; //用em填补e
m += em, em = 0; //把剩下的em分给m
if (m >= mid) { //m满足mid
h += mh, mh = 0; //把mh全部分给h
return (h >= mid)?true:false;//h满足mid
} else { //m不满足mid
int p = mid - m; //m与mid差多少
if (mh >= p) { //mh满足p
m = mid, mh -= p; //用mh填补m
h += mh, mh = 0; //把剩下的mh全部分给h
return (h >= mid)?true:false;//h满足mid
} else { //mh不满足p
return false;
}
}
} else { //em不满足p
return false;
}
}
}
然而事实证明我写check时想多了,考后我读了别人的程序把它改得这么短(太污了)
bool check(int e, int em, int m, int mh, int h, int mid) {
if (e < mid)
em -= mid - e;
if (em < 0)
return false;
else
m += em;
if (m < mid)
mh -= mid - m;
if (mh < 0)
return false;
else
h += mh;
return (h >= mid)?true:false;
}