竞赛链接
目录
- 老君炼丹【算法赛】
- 大意
- 思路
- 拯救美猴王【算法赛】
- 大意
- 思路
- 打卡蓝桥杯周赛!
老君炼丹【算法赛】
大意
有一个数组,每一次可以选择两个元素 a i , a i ≤ 0 a_i,a_i\le0 ai,ai≤0和一个 a j , a j ≥ 0 a_j,a_j\ge0 aj,aj≥0,将他们删除,然后将他们的和 a i + a j a_i+a_j ai+aj作为新元素加入到数组中,问最后能否使得最后数组只剩一个元素
思路
首先,不论如何操作,数组元素之和 s u m sum sum是不变的,那么,数组和为正数时,如果除了最大数之外的元素之和也是正数,最后就会剩下两个正数(想象成用所有负数去消耗剩下的正数,还消耗不完),无法操作;数组和为负数时同理。
具体实现就是,先求数组和,排序,判断即可。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
/***************main****************/
vector<ll> a;
ll sum = 0;
bool sol(ll l, ll r) {
if (sum > 0) {
if (sum - a[r] > 0)
return false;
else
return true;
} else if (sum < 0) {
if (sum - a[0] < 0)
return false;
else
return true;
} else
return true;
}
int main() {
int N;
cin >> N;
for (int i = 0; i < N; ++i) {
ll x;
cin>>x;
sum += x;
a.push_back(x);
}
sort(a.begin(), a.end());
cout << (sol(0, N - 1) ? "Y" : "N");
return 0;
}
拯救美猴王【算法赛】
大意
给定一个大小为
N
N
N的数组,请问有多少个五元组
(
a
,
b
,
c
,
d
,
e
)
(a,b,c,d,e)
(a,b,c,d,e)的下标组合满足以下条件:
1
≤
a
<
b
<
c
<
d
<
e
≤
N
1≤a<b<c<d<e≤N
1≤a<b<c<d<e≤N.
A
a
+
A
b
=
A
c
=
A
d
+
A
e
A_a+A_b=A_c=A_d+ A_e
Aa+Ab=Ac=Ad+Ae
思路
枚举c,并用两个map分别记录[0,i-1],[i+1,n-1]两个区间的满足 A a + A b = A c = A d + A e A_a+A_b=A_c=A_d+ A_e Aa+Ab=Ac=Ad+Ae的数对数量,也就是在[0,i-1]内找满足条件的a,b的数量,在[i+1,n-1]内找满足条件的d,e的数量,将二者数量相乘,就是下标为c对答案的贡献,累加这个贡献即可。
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
/***************main****************/
ll sol(map<ll, ll>& m, ll x) {
ll res = 0;
for (auto& [v, c] : m) {
if (v * 2 == x)
res += (c * (c - 1));
else if (m.find(x - v) != m.end())
res += c * m[x - v];
}
return (res >> 1ll);
}
int main() {
int N;
cin >> N;
vector<ll> A(N);
map<ll, ll> m1, m2;
for (ll i = 0; i < N; ++i) {
cin >> A[i];
m2[A[i]]++;
}
ll ans = 0;
for (ll i = 0; i < N - 2; ++i) {
m2[A[i]]--;
if (i > 1) ans += sol(m1, A[i]) * sol(m2, A[i]);
m1[A[i]]++;
}
cout << ans << endl;
return 0;
}
打卡蓝桥杯周赛!
蓝桥杯比赛界面:
蓝桥杯比赛,奖励丰厚!