admin 题解分享 · 2024/4/16
拔河(编程题) - 题解
原本视频里面的代码已经被hack,因为不小心敲错了一个前缀和,下面是更正后的代码,数据两个代码都能通过,数据运气较好,没有因为标程错误而出现问题。 ```cpp #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1005; ll a[N],pre[N],ans=LLONG_MAX; multiset<ll> s; int main() { int n; cin>>n; for(int i=1;i<=n;i++) cin>>a[i],pre[i]=pre[i-1]+a[i]; for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) s.insert(pre[j]-pre[i-1]); for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) { ll val = pre[i-1]-pre[j-1]; auto it = s.lower_bound(val); if(it!=s.end()) ans=min(ans,abs(*it-val)); if(it!=s.begin()) { --it; ans=min(ans,abs(*it-val)); } } for(int j=i;j<=n;j++) s.erase(s.find(pre[j]-pre[i-1])); } cout<<ans; } ```
查看全文
0 0 4 1
听风与你s6mi7 题解分享 · 2025/4/1
拔河(编程题) - 题解
不一定所有人都被选上 遍历所有的左子数组,然后对右子数组二分查找邻近值。 ``` #include <bits/stdc++.h> using namespace std; using ll = long long; multiset<ll> s; int main() { int n; cin>>n; int a[n+1]; ll sum[n+1] = {0}; for(int i = 1;i<=n;i++) { cin>>a[i]; sum[i] = sum[i-1] + a[i]; //构造前缀和 } for(int i = 1;i<=n;i++) { for(int j = i;j<=n;j++) { s.insert(sum[j] - sum[i-1]); //将所有的区间和存起来 } } ll res = LLONG_MAX; for(int i = 1;i<n;i++) //遍历左子数组的右端点 { for(int j = i;j<=n;j++) //删除所有与右子数组相交的区间 { s.erase(s.find(sum[j] - sum[i-1])); } for(int j = 1;j<=i;j++). //遍历左子数组的左端点,根据左右端点得出左子数组的和,再二分查找最近的右子数组 { ll target = sum[i] - sum[j-1]; auto it = s.lower_bound(target); if(it != s.end()) //第一个>=target的数 res = min(res, abs(target - *it)); if(--it != s.begin()) //最后一个<target的数,因为是绝对值要考虑大于和小于 res = min(res,abs(target - *it)); } } cout<<res; } ```
查看全文
0 0 0 2