比赛链接:https://codeforces.com/contest/1754
A. Technical Support
题目大意:一个字符串表示消息记录,Q代表发送的询问,A代表发送的回答,回答可能有延迟,要求有问有答
题解:任意后缀A需大于Q
#include <bits/stdc++.h>
using namespace std;
const int N = 3 * 1e5;
typedef long long ll;
char s[N];
void solve()
{
int n;
cin >> n;
cin >> s + 1;
map<char, int> mp;
string ans = "Yes";
for(int i = n; i >= 1; i -- )
{
mp[s[i]] ++ ;
if(mp['A'] < mp['Q']) ans = "No";
}
cout << ans << endl;
}
int main()
{
int T;
cin >> T;
while(T -- ) solve();
}
B. Kevin and Permutation
题目大意:求1~n的一个排列使得差分序列的最小值最大
题解:最小值为⌊n/2⌋
#include <bits/stdc++.h>
using namespace std;
const int N = 3 * 1e5;
void solve()
{
int n;
cin >> n;
for(int i = 1; i <= n / 2; i ++ )
{
cout << i + n / 2 << ' ';
cout << i << ' ';
}
if(n & 1) cout << n;
cout << endl;
}
int main()
{
int T;
cin >> T;
while(T -- ) solve();
}
C1/2. Make Nonzero Sum
题目大意:讲序列a拆分成任意长度大于等于1的段,每段的值为Si,要求所有的段加起来等于0
题解:状态机DP,可以抽象看成两条个序列,分别为
v[1] -v[2] v[3] -v[4]…
-v[1] v[2] -v[3] v[4]…
再抽象看成
第一段肯定是第一个序列的前缀,分段等价于转换序列,因为第i段的一个值必定是正的
所以第一个序列只能在奇数处转换到第二个序列,这样后面的段第一个值才能为正
同理第二个序列在偶数处转换序列
f[i][j]代表结尾处在第j+1个序列,取得的最小绝对值
#include <bits/stdc++.h>
using namespace std;
const int N = 3 * 1e5;
typedef long long ll;
typedef pair<int, int> PII;
int a[N], b[N]; //两个序列
int f[N][2];
int g[N][2]; // 记录状态转换
void solve()
{
int n;
cin >> n;
for(int i = 1; i <= n; i ++ )
{
int x;
cin >> x;
a[i] = (i & 1) ? x : -x;
b[i] = (i & 1) ? -x : x;
}
f[1][0] = a[1];
f[1][1] = 1e9;
for(int i = 2; i <= n; i ++ )
{
if(i % 2 == 0)
{
f[i][0] = f[i - 1][0] + a[i];
g[i][0] = 0;
if(abs(f[i - 1][1] + b[i]) < abs(f[i - 1][0] + b[i]))
{
f[i][1] = f[i - 1][1] + b[i];
g[i][1] = 1;
}
else
{
f[i][1] = f[i - 1][0] + b[i];
g[i][1] = 0;
}
}
else
{
f[i][1] = f[i - 1][1] + b[i];
g[i][1] = 1;
if(abs(f[i - 1][1] + a[i]) < abs(f[i - 1][0] + a[i]))
{
f[i][0] = f[i - 1][1] + a[i];
g[i][0] = 1;
}
else
{
f[i][0] = f[i - 1][0] + a[i];
g[i][0] = 0;
}
}
}
if(min(abs(f[n][0]), abs(f[n][1]))) cout << -1 << endl;
else
{
int l = n, r = n, t = abs(f[n][1]) < abs(f[n][0]);
vector<PII> ans;
for(int i = n; i >= 2; i -- )
if(t != g[i][t])
{
ans.push_back({l, r});
l = i - 1;
r = i - 1;
t = g[i][t];
}
else l -- ;
ans.push_back({l, r});
cout << ans.size() << endl;
sort(ans.begin(), ans.end());
for(auto [x, y] : ans)
cout << x << ' ' << y << endl;
}
}
int main()
{
int T;
cin >> T;
while(T -- ) solve();
}