【题解(c++)】「蓝桥·算法双周赛」第十五场分级赛——强者挑战赛

竞赛链接

老君炼丹【算法赛】

大意

有一个数组,每一次可以选择两个元素 a i , a i ≤ 0 a_i,a_i\le0 ai,ai0和一个 a j , a j ≥ 0 a_j,a_j\ge0 aj,aj0,将他们删除,然后将他们的和 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 1a<b<c<d<eN. 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;
}

打卡蓝桥杯周赛!

蓝桥杯比赛界面:
蓝桥杯比赛界面
蓝桥杯比赛,奖励丰厚!
在这里插入图片描述

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值