A. Channel
题意:有n个订阅者,a个初始在线人数,q个上下线情况,问是否一定或有可能所有订阅者都阅读了新的帖子。
思路:同时在线人数等于n时,一定都阅读了,输出YES。初始在线人数加上所有的上线人数(所有的+号)大于等于n的话输出MAYBE。否则输出NO。
AC代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 100010;
void solve()
{
int n, a, q;
cin >> n >> a >> q;
string arr;
cin >> arr;
int jia = a;
if (a == n)
{
cout << "YES" << endl;
return;
}
for (int i = 0; i < arr.size(); i++)
{
jia += (arr[i] == '+');
a += (arr[i] == '+');
a -= (arr[i] == '-');
if (a == n)
{
cout << "YES" << endl;
return;
}
}
if (jia >= n)
{
cout << "MAYBE" << endl;
return;
}
cout << "NO" << endl;
}
signed main()
{
int t;
cin >> t;
//t = 1;
while (t--)
{
solve();
}
}
B. Split Sort
题意:给出一个排列,可以进行一个操作:选定一个数后,按原先顺序先写出小于这个数的数,再写出大于这个数的数。问最少需要多少步可以使ai = i。
思路:对于一个数a,如果它的位置要大于a + 1的话,那么必须选定a + 1来操作一次,记录所有这样的数的和,即为最小步数。
AC代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 100010;
int a[N], p[N];
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
p[a[i]] = i;
}
int ans = 0;
for (int i = 1; i < n; i++)
{
ans += (p[i] > p[i + 1]);
}
cout << ans << endl;
}
signed main()
{
int t;
cin >> t;
//t = 1;
while (t--)
{
solve();
}
}
C. MEX Repetition
题意:给出一个数列,对数列进行k次下列操作:从a1到an,依次用数列的MEX值替代,数列的MEX值为没有出现在数列中的最小值。
思路:当对数列进行n + 1次操作时,数列会变回初始情况,所以k要先模一下n + 1,每做一次操作相当于滑动数组向右滑动了一次,例如1 2 3 4 5每次操作后为:
0 1 2 3 4
5 0 1 2 3
4 5 0 1 2
3 4 5 0 1
2 3 4 5 0
1 2 3 4 5
数列的MEX值为1到n + 1的和减去当前数列的和。
AC代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 100010;
int a[N];
int d[N];
void solve()
{
int n, k;
cin >> n >> k;
int sum = 0;
int p = (n + 1) * n / 2;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}
a[n + 1] = p - sum;
n += 1;
if (k == n)
{
for (int i = 1; i <= n - 1; i++)
cout << a[i] << " ";
cout << endl;
return;
}
if (k > n)
{
int x = k % n;
k = x;
}
for (int i = n - k + 1; i <= n; i++)
{
cout << a[i] << " ";
}
for (int i = 1; i <= n - k - 1; i++)
{
cout << a[i] << " ";
}
cout << endl;
}
signed main()
{
d[0] = 0;
for (int i = 1; i <= 100000; i++)
{
d[i] = d[i - 1] + i;
}
int t;
cin >> t;
//t = 1;
while (t--)
{
solve();
}
}
D. Two-Colored Dominoes
题意:棋盘上有若干个多米诺骨牌,每个牌占据两个格子,上下两个或者左右两个。要求用黑白颜色给多米诺骨牌涂色,每个多米诺骨牌的两个格子必须不同颜色,同一列和同一行的黑白颜色数必须相等。如果不能输出-1。
思路:如果在同一行或同一列的多米诺骨牌所在格子为奇数,则不可能涂色。横着的多米诺不会影响这一行的得黑白数,竖着的不会影响这一列的黑白数。所以遍历每一行,将每个竖着的多米诺依次涂成黑,白,黑,白....(竖着的多米诺每一行一定有偶数个)。遍历每一列,将每个横着的多米诺依次涂为黑,白,黑,白.....(横着的多米诺每一列一定有偶数个)。
AC代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#define int long long
using namespace std;
const int N = 510;
char arr[N][N];
int ans[N][N], col[N], lie[N];
int colsum[N], liesum[N];
typedef pair<int, int> pll;
int n, m;
int check()
{
memset(colsum, 0, sizeof colsum);
memset(liesum, 0, sizeof liesum);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
//cin >> arr[i][j];
if (arr[i][j] != '.')
{
colsum[i]++;
liesum[j]++;
}
}
int flag = 1;
for (int i = 1; i <= n; i++)
{
if (colsum[i])flag = 0;
if (colsum[i] % 2)
{
cout << -1 << endl;
return 1;
}
}
for (int j = 1; j <= m; j++)
{
if (liesum[j] % 2)
{
cout << -1 << endl;
return 1;
}
}
if (flag)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cout << '.';
}
cout << endl;
}
return 1;
}
return 0;
}
void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> arr[i][j];
}
}
if (check())
{
return;
}
int cnt = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (arr[i][j] == 'U')
{
ans[i][j] = cnt;
ans[i + 1][j] = cnt * -1;
cnt *= -1;
}
}
}
cnt = 1;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (arr[j][i] == 'L')
{
ans[j][i] = cnt;
ans[j][i + 1] = cnt * -1;
cnt *= -1;
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (arr[i][j] == '.')
{
cout << ".";
continue;
}
if (ans[i][j] == 1)
{
cout << "W";
}
else cout << "B";
}
cout << endl;
}
}
signed main()
{
int t;
cin >> t;
//t = 1;
while (t--)
{
solve();
}
}