CF_2153_C. Symmetrical Polygons
题目链接:Problem - C - Codeforces
题目大意:
有 n 根木棍,第 i 根木棍的长度是 a[i], 要用这些木棍搭建一个多边形
要求:
- 不允许把 两根或以上 的木棍首尾相接并排成一条更长的边。
- 所有内角都严格小于180°
- 该图形 对称
- 相邻 两边部分不重合
思路:
先记录每个长度的小木棒出现的次数,
我们优先把多边形的两侧建立起来
题目要求的多边形是:相邻两边部分不重合,没有角等于 180,不允许把两根或以上的木棍首尾相接并排成一条更长的边
把出现偶数次的边放到两侧,一侧的两边连接时可以看成近似180°
这样就可以近似看成是四边形或是三边形
对于奇数次且出现次数>=3的小木棒,可以看成是 1 + ( 次数-1 ) , 右侧部分又是一个偶数次,拆下来拼在两侧
现在剩下的都是还能用 1 次的小木棒
然后再拼上下两部分,注意如果一边的边长>=其余的边长,那这种情况就拼不了
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 500086, mod = 998244353;
int n, m;
int a[N];
void solve() {
cin >> n;
map<int, int> mp;
for (int i = 1; i <= n; i++) {
cin >> a[i];
mp[a[i]]++;
}
int tt = 0, cnt = 0;
vector<int> q;
for (auto x : mp) {
if (x.S % 2 == 0) {
tt += x.F * x.S;
cnt += x.S;
} else {
if (x.S >= 3) {
tt += x.F * (x.S - 1);
cnt += (x.S - 1);
}
q.push_back(x.F);
}
}
sort(q.begin(), q.end());
int res = 0;
if (cnt >= 3) res = tt;
if (cnt < 2) {
cout << 0 << endl;
return;
}
if (q.size() == 0);
else {
for (auto x : q) {
if (tt > x) res = max(res, tt + x);//尝试只加用一条边的情况
}
for (int i = 0; i < q.size() - 1 ; i++) {
if (tt + q[i] > q[i + 1]) {
res = max(res, tt + q[i] + q[i + 1]);//尝试再加两条边的情况
}
}
}
cout << res << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号