当s的长度为偶数时去掉最中间的两个字符,奇数时去掉最中间的字符,判断剩下的字符种类是否大于两种即可。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while (T--){
string s;
cin >> s;
map<char, int> mp;
int n = s.size() / 2;
if (s.size() % 2) n--;
for (int i = 0; i <= n; i++){
mp[s[i]]++;
}
if (mp.size() >= 2)cout << "YES\n";
else cout << "NO\n";
}
return 0;
}
前缀和预处理之后,枚举所有可能。
ll maxn = -1e9;
for (int i = 0; i <= k; i++){
ll ans = sum[n];
ans -= sum[i * 2];
ans -= sum[n] - sum[n - (k - i)];
maxn = max(maxn, ans);
}
cout << maxn << '\n';
优化为
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while (T--){
int n, k;
cin >> n >> k;
vector<ll> a(n + 1), sum(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a.begin() + 1, a.end());
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + a[i];
}
ll maxn = -1e9;
for (int i = 0; i <= k; i++){
ll ans = sum[n - (k - i)] - sum[i * 2];
maxn = max(maxn, ans);
}
cout << maxn << '\n';
}
return 0;
}
可以发现对于一段单调的区间,可以只保留开头和结尾的两个数,所以直接求出极值个数即可。
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while (T--){
int n;
cin >> n;
vector<int> a(n + 2), b;
map<int, int> mp;
for (int i = 1; i <= n; i++){
cin >> a[i];
mp[a[i]]++;
}
b.push_back(-1);
b.push_back(a[1]);
for (int i = 2; i <= n; i++){
if (a[i] != a[i - 1]) b.push_back(a[i]);
}
b.push_back(-1);
if (mp.size() == 1){
cout << 1 << '\n';
continue;
}
int cnt = 0;
int x = b.size() - 2;
for (int i = 1; i <= x; i++){
if ((b[i] > b[i - 1] && b[i] > b[i + 1]) || (b[i] > b[i - 1] && i == x) || (i == 1 && b[i] > b[i + 1])) cnt++;
else if ((b[i] < b[i - 1] && b[i] < b[i + 1]) || (b[i] < b[i - 1] && i == x) || (i == 1 && b[i] < b[i + 1])) cnt++;
}
cout << cnt << '\n';
}
return 0;
}