本文主要是介绍模拟题1(考虑周全以及情况较多),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
牛客小白月赛96(重现赛)D题
题目解析以及注意事项
该题主要是找线路最多和最少的各种情况,从而达到整体连通图的构建代价最小的情况。
注意事项:a,b的正负影响着这个图的线尽可能的多还是少
思路图
{ a ≥ b { b < 0 a < 0 : 能连的线都连上 b < 0 a ≥ 0 :奇偶性不同线能连的的全连上 b > 0 :连奇偶性不同的点,而且线的数量要尽量小 a < b { a < 0 b < 0 : 能连的线都连上 a < 0 b ≥ 0 : 奇偶性相同的点互相之间能连的都连上,最后连一个奇偶性不同的点以形成连通图 a > 0 : 奇偶性相同的点互相之间连上,而且尽量少,最后连一个奇偶性不同的点 \begin{cases}a\geq b & \begin{cases}b<0 & a<0:能连的线都连上\\ b<0 & a\geq0:奇偶性不同线能连的的全连上\\ b>0 & :连奇偶性不同的点,而且线的数量要尽量小\end{cases}\\ a<b & \begin{cases}a<0 & b<0:能连的线都连上\\ a<0 & b\geq0:奇偶性相同的点互相之间能连的都连上,最后连一个奇偶性不同的点以形成连通图\\ a>0 & :奇偶性相同的点互相之间连上,而且尽量少,最后连一个奇偶性不同的点\end{cases}\end{cases} ⎩ ⎨ ⎧a≥ba<b⎩ ⎨ ⎧b<0b<0b>0a<0:能连的线都连上a≥0:奇偶性不同线能连的的全连上:连奇偶性不同的点,而且线的数量要尽量小⎩ ⎨ ⎧a<0a<0a>0b<0:能连的线都连上b≥0:奇偶性相同的点互相之间能连的都连上,最后连一个奇偶性不同的点以形成连通图:奇偶性相同的点互相之间连上,而且尽量少,最后连一个奇偶性不同的点
注意事项
当考虑n个点之间所有能连的都连上的时候,线的数量count为
n ∗ ( n − 1 ) 2 \frac{n*(n-1)}{2} 2n∗(n−1)
注意n数据范围是
1 ≤ n ≤ 2 e 5 1\leq n\leq 2e^5 1≤n≤2e5
而count如果不开long long会超,(呜呜呜,因为这个又多WA了一发)
其他情况同理需要考虑,所以最好全开ll。
#define ll=long long;
key代码实现
odd记录数组中奇数的个数,even记录数组中偶数的个数。
if(odd==0||even==0){if(a>=0)cout<<(n-1)*a<<endl;else cout<<(odd*(odd-1)>>1)*a+(even*(even-1)>>1)*a<<endl;return;}if(b<=a){if(b>=0) cout<<(odd+even-1)*b<<endl;else if(a>=0) cout<<odd*even*b<<endl;else if(a<0) cout<<odd*even*b+(odd*(odd-1)>>1)*a+(even*(even-1)>>1)*a<<endl;return;}else {if(a>=0)cout<<(odd+even-2)*a+b<<endl;else if(b>=0) cout<<((odd*(odd-1)>>1)+(even*(even-1)>>1))*a+b<<endl;else cout<<((odd*(odd-1)>>1)+(even*(even-1)>>1))*a+b*odd*even<<endl;}
完整代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define For for (ll i = 1; i <= n; i++)
#define rFor for (ll i = n; i > 0; i--)
#define rep(i, sta, end) for (ll i = sta; i <= end; i++)
#define rrep(i, end, sta) for (ll i = end; i >= sta; i--)
#define ALL(x) for (auto item : x)inline void solve() {ll n,a,b;cin>>n>>a>>b;ll odd=0,even=0;ll tmp;For {cin>>tmp;odd+=(tmp%2==1);even+=(tmp%2==0);}if(n==1){cout<<0<<endl;return;}if(odd==0||even==0){if(a>=0)cout<<(n-1)*a<<endl;else cout<<(odd*(odd-1)>>1)*a+(even*(even-1)>>1)*a<<endl;return;}if(b<=a){if(b>=0) cout<<(odd+even-1)*b<<endl;else if(a>=0) cout<<odd*even*b<<endl;else if(a<0) cout<<odd*even*b+(odd*(odd-1)>>1)*a+(even*(even-1)>>1)*a<<endl;return;}else {if(a>=0)cout<<(odd+even-2)*a+b<<endl;else if(b>=0) cout<<((odd*(odd-1)>>1)+(even*(even-1)>>1))*a+b<<endl;else cout<<((odd*(odd-1)>>1)+(even*(even-1)>>1))*a+b*odd*even<<endl;}
}int main() {ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);ll num = 1;cin >> num;while (num--) {//cout << "Main function execute properly before solve function " << endl;solve();// cout << "Main function execute properly after solve function" << endl;}return 0;
}
这篇关于模拟题1(考虑周全以及情况较多)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!