A
判断连续出现的相同字符是偶数还是奇数
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
const int maxn = 1e5 + 5;
int vis[30];
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
string s; cin >> s;
int n = s.size();
memset(vis, -1, sizeof(vis));
char pre; int cnt = 0;
for (int i = 0; i < n; ++i) vis[s[i] - 'a'] = 1;
for (int i = 0; i < n; ++i) {
if (i == 0) pre = s[i], cnt = 1;
else {
if (s[i] == pre) cnt++;
else {
if (cnt & 1) vis[pre - 'a'] = 0;
pre = s[i], cnt = 1;
}
}
}
if (cnt & 1) vis[pre - 'a'] = 0;
for (int i = 0; i < 26; ++i) {
if (vis[i] == 0) cout << (char)(i + 'a');
}
cout << endl;
}
}
B
问题即求给出n个0,m个1。求给出多个串长度,求能组成最多的回文串数目
串越短越容易满足。对串长度为奇数,需要优先使用01中数量为奇数的
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
const int maxn = 50 + 5;
string str;
int len[maxn];
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
int n; cin >> n;
int cnt0 = 0, cnt1 = 0;
for (int i = 0; i < n; ++i) {
cin >> str; len[i] = str.size();
for (int j = 0; j < len[i]; ++j) {
if (str[j] == '0') cnt0++;
else cnt1++;
}
}
sort(len, len + n);
int ans = 0;
for (int i = 0; i < n; ++i) {
if (len[i] & 1) {
if ((cnt0 & 1) && cnt0 >= len[i]) cnt0 -= len[i], ans++;
else if ((cnt1 & 1) && cnt1 >= len[i]) cnt1 -= len[i], ans++;
else {
if (cnt0 & 1) cnt1 -= len[i] - cnt0, cnt0 = 0, ans++;
else cnt0 -= len[i] - cnt1, cnt1 = 0, ans++;
}
}
else {
if (cnt0 + cnt1 > len[i]) {
if (cnt0 >= len[i]) cnt0 -= len[i], ans++;
else if (cnt1 >= len[i]) cnt1 -= len[i], ans++;
else {
cnt1 -= len[i] - cnt0;
cnt0 = 0;
ans++;
}
}
else if (cnt0 + cnt1 == len[i]) {
if ((cnt0 & 1) || (cnt1 & 1)) continue;
cnt1 -= len[i] - cnt0;
cnt0 = 0;
ans++;
}
}
}
cout << ans << endl;
}
}
C
对奇偶分组,队友过题
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
const int maxn = 1000005;
string str;
vector<int> odd, even;
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while(t--)
{
cin >> str; int m = str.size();
odd.clear(), even.clear();
for (int i = 0; i < m; ++i) {
if ((str[i] - '0') & 1)
odd.push_back((int)(str[i] - '0'));
else even.push_back((int)(str[i] - '0'));
}
even.push_back(10); odd.push_back(10);
int oddl = 0, evenl = 0;
while (true) {
if (oddl >= odd.size() - 1 && evenl >= even.size() - 1) break;
else {
if (even[evenl] < odd[oddl]) {
cout << even[evenl];
evenl++;
}
else {
cout << odd[oddl];
oddl++;
}
}
}
cout << endl;
}
return 0;
}
D
二分
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int maxn = 1000005;
int l[maxn],r[maxn],n;
int a[maxn];
int vis[maxn];
ll cnt, sum;
int check(int mid)
{
int k=0;
long long int men=0;
int dy=0;
for(int i=1;i<=n;i++)
{
if(l[i]>=mid)
{
dy++;
}
else if(r[i]>=mid)
{
vis[++k]=mid-l[i];
}
}
if(dy+k<n/2+1)
return 0;
sort(vis+1,vis+k+1);
for(int i=1;i<=n/2+1-dy;i++)
{
men=men+(long long int)(vis[i]);
}
if(men+cnt<=sum)
return 1;
return 0;
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--)
{
cnt=0, sum=0; cin >> n >> sum;
for(int i=1;i<=n;i++)
{
cin >> l[i] >> r[i];
a[i] = l[i];
cnt += (ll)(l[i]);
}
sort(a + 1, a + n + 1);
int ll = a[n / 2 + 1], rr = 1e9 + 1, mid;
while (ll < rr) {
mid = (ll + rr) >> 1;
if (check(mid)) ll = mid + 1;
else rr = mid;
}
if (check(rr)) cout << rr << endl;
else if (check(mid)) cout << mid << endl;
else if (check(ll - 1)) cout << ll - 1 << endl;
}
return 0;
}
E
贪心,对当前人数为i时,若存在m属于(0,i-1)的人,我们优先选择p大的进入(即免费)
用线段树维护对m最大的p,查询完修改m。用multiset保存
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int maxn = 2e5 + 5;
int n, p[maxn], m[maxn];
multiset<int> st[maxn];
int val[maxn << 2], pos[maxn << 2];
void build(int rt = 1, int l = 0, int r = n) {
if (l == r) {
if (st[l].size() == 0) val[rt] = 0;
else { val[rt] = *st[l].rbegin(); st[l].erase(--st[l].end()); }
pos[rt] = l;
return;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid); build(rt << 1 | 1, mid + 1, r);
if (val[rt << 1] > val[rt << 1 | 1]) { val[rt] = val[rt << 1]; pos[rt] = pos[rt << 1]; }
else { val[rt] = val[rt << 1 | 1]; pos[rt] = pos[rt << 1 | 1]; }
}
pair<int, int> query(int L, int R, int rt = 1, int l = 0, int r = n) {
if (L <= l && r <= R) return make_pair(val[rt], pos[rt]);
int mid = (l + r) >> 1;
pair<int, int> res = make_pair(0, 0);
if (L <= mid) res = max(res, query(L, R, rt << 1, l, mid));
if (mid < R) res = max(res, query(L, R, rt << 1 | 1, mid + 1, r));
return res;
}
void modify(int loc, int rt = 1, int l = 0, int r = n) {
if (l == r) {
if (st[l].size() == 0) val[rt] = 0;
else { val[rt] = *st[l].rbegin(); st[l].erase(--st[l].end()); }
return;
}
int mid = (l + r) >> 1;
if (loc <= mid) modify(loc, rt << 1, l, mid);
else modify(loc, rt << 1 | 1, mid + 1, r);
if (val[rt << 1] > val[rt << 1 | 1]) { val[rt] = val[rt << 1]; pos[rt] = pos[rt << 1]; }
else { val[rt] = val[rt << 1 | 1]; pos[rt] = pos[rt << 1 | 1]; }
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0);
int t; cin >> t;
while (t--) {
cin >> n;
ll ans = 0;
for (int i = 0; i <= n; ++i) st[i].clear();
for (int i = 0; i < n; ++i) {
cin >> m[i] >> p[i];
st[m[i]].insert(p[i]);
ans += p[i];
}
build();
for (int i = 1; i <= n; ++i) {
pair<int, int> res = query(0, i - 1);
if (res.first == 0) continue;
ans -= res.first;
modify(res.second);
}
cout << ans << endl;
}
}