比较开心能做出D
A
原题
A. A Gift From Orangutan
思路
找到最大值最小值差值乘n - 1 即可
代码
#include <bits/stdc++.h>
#define int long long
#define F(i, a, b) for (int i = (a); i <= (b); i++)
#define dF(i, a, b) for (int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 500005, M = (N << 1), inf = 1e16, mod = 1e9 + 7;
int n, m, k, x, y, z, ans, t;
int w[N], f[N];
void solve()
{
cin >> n;
int minn = 2000, maxx = 0;
for (int i = 1; i <= n; i ++ )
{
cin >> x;
minn = min(minn, x);
maxx = max(maxx, x);
}
cout << (maxx - minn) * (n - 1) << "\n";
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T -- )
{
solve();
}
}
B
原题
B. Minimise Oneness
思路
1 会与任何只有 0 的子序列形成一个子序列, 所以只要一个 1 就够了
代码
#include <bits/stdc++.h>
#define int long long
#define F(i, a, b) for (int i = (a); i <= (b); i++)
#define dF(i, a, b) for (int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 500005, M = (N << 1), inf = 1e16, mod = 1e9 + 7;
int n, m, k, x, y, z, ans, t;
int w[N], f[N];
void solve()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
{
if (i == n)
{
cout << 1;
}
else
{
cout << 0;
}
}
cout << "\n";
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T -- )
{
solve();
}
}
C
原题
C. A TRUE Battle
思路
and 优先级比 or 高
所以只要有1在开头或结尾 或者有两个连续的 1, 就一定 alice 获胜
代码
#include <bits/stdc++.h>
#define int long long
#define F(i, a, b) for (int i = (a); i <= (b); i++)
#define dF(i, a, b) for (int i = (a); i >= (b); i--)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 500005, M = (N << 1), inf = 1e16, mod = 1e9 + 7;
int n, m, k, x, y, z, t;
int w[N], f[N];
void print( bool ans)
{
if (ans)
{
cout << "YES" << "\n";
}
else
{
cout << "NO" << "\n";
}
}
void solve()
{
cin >> n;
string s;
cin >> s;
bool ans = false;
if (s[0] == '1' || s[n - 1] == '1')
{
ans = true;
print(ans);
return;
}
for (int i = 0; i < n - 1; i ++ )
{
if (s[i] == '1' && s[i + 1] == '1')
{
ans = true;
}
}
print(ans);
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T -- )
{
solve();
}
}
D
原题
D. QED's Favorite Permutation
思路
首先我们可以把 p 数组的 n 个数之间的 n - 1 个空挡看作 n - 1 个通道, 这个通道有两种状态, 一种是开启, 一种是关闭, 如果开启, 意味着可以交换左右两个数
由于 p 数组是不会变的, 所以我们可以求出哪些通道需要是开启的才可以将数组排列好
我们可以简单的从前往后遍历来确定哪些通道需要开启, 如果到第 i 个数时, 前面的所有数中最大值大于i, 说明有数需要从前面移动到后面, 因此第 i 个通道需要是开启的
我们比较需要开启的和实际开启的, 可以得知不符合的通道有几个
每次修改时, 会改变两个通道的状态, 只需要维护好就可以了
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, m, k, q, x, y, z, ans, t;
int p[N], f[N], g[N];
string s;
void print()
{
if (ans == 0)
{
cout << "YES" << "\n";
}
else
{
cout << "NO" << "\n";
}
}
int check(int pos)
{
if (s[pos] == 'R' || s[pos + 1] == 'L')
return 1;
else
return 0;
}
int check2(int pos)
{
if (g[pos] == 1 && f[pos] == 0)
{
return 1;
}
else
return 0;
}
void solve()
{
cin >> n >> q;
int len = 0;
for (int i = 1; i <= n; i ++ )
{
cin >> p[i];
len = max (len, p[i]);
if (i < len)
g[i] = 1;
else
g[i] = 0;
}
cin >> s;
ans = 0;
for (int i = 0; i < n - 1; i ++ )
{
f[i + 1] = check(i);
}
for (int i = 1; i < n; i ++ )
{
ans += check2(i);
}
for (int i = 1; i <= q; i ++ )
{
cin >> x;
if (s[x - 1] == 'L')
{
s[x - 1] = 'R';
}
else
{
s[x - 1] = 'L';
}
if (x - 1 > 0) ans -= check2(x - 1);
if (x <= n - 1) ans -= check2(x);
if (x - 1 > 0) f[x - 1] = check(x - 2);
if (x <= n - 1) f[x] = check(x - 1);
if (x - 1 > 0) ans += check2(x - 1);
if (x <= n - 1) ans += check2(x);
print();
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T = 1;
cin >> T;
while (T -- )
{
solve();
}
}