C、剧本杀
根据题意,到达位置算邀请成功,但邀请下一个人需要返回后重新前往。因此可以采用贪心,每次邀请都邀请距离最近的。将所有的距离(距离为x的绝对值加y的绝对值)从小到大排序,每次判断是否体力够单程到达,如果够单程到达,ans++,同时将体力减少2倍的单程,继续判断下一个,如果不能单程到达则输出答案。
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
long long a[N];
int main() {
long long n,k;
cin>>n>>k;
for(int i=0;i<n;i++){
long long x,y;
cin>>x>>y;
a[i]=(abs(x)+abs(y));
}
sort(a,a+n);
long long ans=0;
for(int i=0;i<n;i++){
if(a[i]<=k){
ans++;
k-=2*a[i];
}else{
break;
}
}
cout<<ans;
return 0;
}
F 能找到吗?
将数组从大到小排序后,从头开始遍历数组,通过判断相邻元素是否不同,来统计不同元素的个数。如果能找到四个不同的元素,就输出第四大的元素,否则输出最大的元素。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> nums(n);
for(int i = 0; i < n; i++) {
cin >> nums[i];
}
sort(nums.begin(), nums.end(), greater<int>());
for (int i = 1, diff = 1; i < nums.size(); ++i) {
if (nums[i] != nums[i - 1] && ++diff == 4) {
cout << nums[i] << endl;
return 0;
}
}
cout << nums[0] << endl;
return 0;
}
H 竞争
/*
/*
1 2 3 4 5
1 1 1 1 1 差分
1 2 3 4 5 差分的前缀和就是原数组
*/
想要a变成b
就只需要要他们的差变成0
eg
5
1 5 3 3 5
1 2 2 2 2
0 3 1 1 3 就是让他们的差变成0
求他们的差分数组 (因为要操作一个区间)
每次操作两点 就是操作一个区间
然后就是正负数的绝对值取max
*/
void solve(){
cin >> n;
fr(i,1,n) cin >> a[i];
fr(i,1,n) cin >> b[i],b[i] -= a[i];
fr(i,1,n){
c[i] += b[i];
c[i+1] -= b[i];
}
int p = 0,q = 0;
for(int i = 1;i<=n;i++){
// cout << c[i] << '\n';
if(c[i] > 0) p+=c[i];
else q-=c[i];
}
cout << max(p,q) << '\n';
}
K 拼夕夕
题意:给定一个数t, 和一个数组a, 每次从数组中选择一个数x(这个数最多选择5次), 执行 t -= x,x -= k。使 t <= 0 的最小次数
显然就是每次选择数组中最大的数,用一个优先队列来维护这些值,同时记录下来这个数还可以选多少次。注意数据范围
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;
signed main() {
int total, n, k;
cin >> total >> n >> k;
vector<int> a(n);
priority_queue<pii, vector<pii>, less<pii>> pq;
for(int i = 0; i < n; i++) cin >> a[i], pq.push({a[i], 5});
int ans = 0;
while(pq.size() && total > 0) {
auto [x, cnt] = pq.top();
pq.pop();
total -= x;
x -= k, cnt--;
ans++;
if(x <= 0 || cnt == 0) continue;
pq.push({x, cnt});
}
if(total <= 0) {
cout << ans << endl;
}else{
cout << -1 << endl;
}
}