一开始的思路就是想着暴力,但是呢,如果真的用暴力一个一个列的话,连30%的数据都搞定不了,所以这里需要考虑别的办法。
这道题的思路就是贪心。
我们这样想:既然要满足至少一个国X>Y+Z,那么我们何不变成X-Y-Z>0呢?这样可能会更好想一点。我们就这样存储每一个事件发生之后的差,然后进行排序。
注意,这里的排序是最重要的一步,我们进行排序的目的就是为了找出最合适的选择的个数。
也就是说,我们从大的差值开始往下累加,这个时候和可能会变小,也可能会变大,取决于发生这件事之后的差值是如何的。所以,这就是一种贪心的思想。
注意,我们有三个国,所以要依次算出每个国赢的时候最多发生了多少个事件,所以需要比较3次,看看哪一个国赢的时候发生的事件最多。
上代码:
- #include<iostream>
- #include<stdio.h>
- #include<cstring>
- #include<cstdlib>
- #include<cmath>
- #include<vector>
- #include<algorithm>
- #include<stack>
- #include<queue>
- #include<sstream>
- #include<map>
- #include<limits.h>
- #include<set>
- #define MAX 100010
- #define _for(i,a,b) for(int i=a;i<(b);i++)
- #define ALL(x) x.begin(),x.end()
- using namespace std;
- typedef long long LL;
- typedef pair<int, int> PII;
- LL n, m, counts, num;
- LL a[MAX];
- LL b[MAX];
- LL c[MAX];
- LL res = INT_MIN;
- bool cmp(LL a, LL b)
- {
- return a >= b;
- }
- LL solve(LL a[],LL b[], LL c[]) {
- LL cnt = 0;
- vector<LL>tmp;
- for (int i = 0; i < n; i++) {
- tmp.push_back(a[i] - b[i] - c[i]);//存储差值
- }
- sort(tmp.begin(), tmp.end(), cmp);//对各个事件之后的差值进行排序
- LL sum = 0;
- for (int i = 0; i < n; i++) {
- if (sum + tmp[i] > 0) {//从最大的差值开始累加,满足条件那么就是一个事件,cnt+1
- cnt++;
- sum += tmp[i];
- }
- else break;
- }
- return cnt;
- }
- int main() {
- ios::sync_with_stdio(false);
- cin.tie(NULL); cout.tie(NULL);
- cin >> n;
- for (int i = 0; i < n; i++)
- cin >> a[i];
- for (int i = 0; i < n; i++)
- cin >> b[i];
- for (int i = 0; i < n; i++)
- cin >> c[i];
- res = solve(a, b, c);//对于a赢时发生的最多事件
- res = max(res, solve(b, c, a));//b赢时发生的最多事件,后面两个的顺序是无所谓的。
- res = max(res, solve(c, b, a));//c赢时发生的最多事件。
- cout << res;
- return 0;
- }