文章目录
题目链接
A.Casimir’s String Solitaire
Sol:判断b的数量是否等于a与c的和
Code:
#define ok() cout << "Yes\n"
#define gg() cout << "No\n"
void solve()
{
string s;
cin >> s;
int a, b, c;
a = b = c = 0;
for(int i = 0; i < s.size(); ++i)
{
a += (s[i] == 'A');
b += (s[i] == 'B');
c += (s[i] == 'C');
}
if(b == a + c) ok();
else gg();
}
B.Shifting Sort
Sol:
n
≤
50
n \le 50
n≤50,故可以暴力模拟,每次把最小的放在前面。
Code:
const int N = 100;
int a[N];
void solve()
{
int n;
cin >> n;
rep(i, 1, n ){
cin >> a[i];
}
map<PII, int> ans;
for(int i = 1; i <= n ; ++i)
{
int id = i, mi = a[i];
for(int j = i + 1; j <= n; ++j)
{
if(a[j] < mi)
{
id = j;
mi = a[j];
}
}
int tt = id - i;
if(tt)
{
ans[{i, n}] = tt;
while(tt -- ) {
int pre = a[i];
for(int j = i; j < n; ++j)
{
a[j] = a[j + 1];
}
a[n] = pre;
}
}
}
cout << ans.size() << endl;
for(auto &it : ans)
{
cout << it.first.first << " " << it.first.second << " " << it.second << endl;
}
}
C. Ticks
Sol:
n
,
m
≤
10
n,m \le 10
n,m≤10, 依旧暴力判断。。
Code:
void solve()
{
int n, m, k;
cin >> n >> m >> k;
string s[n];
rep(i, 0, n - 1) cin >> s[i];
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++ j)
{
if(s[i][j] == '*') {
int d = 0;
while( i-d > 0 && j + d +1< m && j - d > 0 && s[i-d-1][j-d-1] != '.' && s[i-d-1][j+d+1] != '.')
++ d;
if(d >= k) {
s[i][j] = '+';
for(int h = 1; h <= d; ++h)
{
s[i-h][j+h] = '+';
s[i-h][j-h] = '+';
}
}
}
}
bool ok = true;
for(int i = 0;i < n; ++i)
for(int j = 0; j < m; ++j)
if(s[i][j] == '*')
ok = false;
if(ok) ok();
else gg();
}
D.roductive Meeting
Sol: 贪心, 将所有不为零的放入大根堆,每次取出两个作为一对。
Code:
void solve()
{
int n;
cin >> n;
PII a[n + 1];
priority_queue<PII>q;
while(q.size()) q.pop();
rep(i, 1, n) {
cin >> a[i].first;
a[i].second = i;
if(a[i].first != 0) q.push(a[i]);
}
vector<PII>ans;
while(q.size() >= 2)
{
PII p = q.top(); q.pop();
PII y = q.top(); q.pop();
ans.push_back({p.second, y.second});
if(p.first > 1) q.push({p.first - 1, p.second});
if(y.first > 1) q.push({y.first - 1, y.second});
}
cout << ans.size() << endl;
for(auto &it : ans)
cout << it.first << " " << it.second << endl;
}
E1.Permutation Minimization by Deque
Sol: 利用deque,大的放后面,小的放前面。
Code:
void solve()
{
int n;
deque<int>q;
cin >> n;
VI a(n);
for(auto &x : a) cin >> x;
for(auto &x : a){
if(q.size() == 0) q.push_back(x);
else {
int st = q.front();
if(x <= st) q.push_front(x);
else q.push_back(x);
}
}
while(q.size()) cout << q.front() << " ", q.pop_front();
br;
}
E2.Array Optimization by Deque
Sol:
两种情况:
- 放前面,答案为后面比这个数小的个数。
- 放后面,答案为前面比这个数大的个数
首先离散化,利用树状数组动态维护区间数的个数。
Code:
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
const int N = 1000010;
int n;
int tr[N];
int a[N];
int lowbit(int x){
return x & -x;
}
void add(int x, int c) {
for(int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}
int sum(int x){
int res = 0;
for(int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
}
void solve()
{
memset(tr, 0, sizeof tr);
scanf("%lld", &n);
vector<int>all;
for(int i = 1; i <= n; ++i)
{
scanf("%lld", &a[i]);
all.push_back(a[i]);
}
// 离散化
sort(all.begin(), all.end());
all.erase(unique(all.begin(), all.end()), all.end());
for(int i = 1; i <= n; ++i) a[i] = lower_bound(all.begin(), all.end(), a[i]) - all.begin() + 1;// +1防止出现负数下标
int ans = 0;
for(int i = 1; i <= n; ++ i)
{
int hh = sum(a[i] - 1), tt = sum(n) - sum(a[i]);
if(hh <= tt) {
ans += hh;
}
else ans += tt;
add(a[i], 1);
}
cout << ans << endl;
}
signed main()
{
int tt; scanf("%lld", &tt);
while(tt -- ) solve();