A - A+B?
题意:给出两个0~9的数字和一个加号。要求输出数字相加的和
思路:用字符串输入,第一位和第三位相加减去两个字符0即为数字和。
void solve() {
string s;
cin >> s;
cout << s[0] + s[2] - 2 * '0' << endl;
}
\[\]B - Matrix Rotation
题意:给出2*2的矩阵,要求每列第一个数字小于第二个数字,每行第一个数字小于第二个数字。你可以对矩阵进行顺时针旋转。问任意给出一个矩阵,是否能通过旋转让矩阵满足要求
思路:由题意可知,第一行第一个数字是最小的,第二行第二个数字是最大的。其余两个数字一定在这两个数字范围内。且最大值和最小值之间一定相隔两位。判断一下即可。
void solve() {
int b[2][2] = {0};
int minv = INF, maxv = -INF;
for (int i = 0; i < 2; i ++)
for (int j = 0; j < 2; j ++) {
cin >> b[i][j];
minv = min(b[i][j], minv);
maxv = max(b[i][j], maxv);
}
if (b[0][0] == maxv && b[1][1] == minv || b[0][0] == minv && b[1][1] == maxv || b[0][1] == maxv && b[1][0] == minv || b[0][1] == minv && b[1][0] == maxv) {
cout << "YES" << endl;
}else cout << "NO" <<endl;
}
\[\]C - Different Differences
题意:在1~n中找到k个数字,使序列中相邻两个数字的差值种类数最多。
思路:因本题数据很小。所以进行\(k^2\)次循环,第一层循环控制从哪个数字开始进行2,3,4...的累加。第二层控制看如果从当前数字开始累加,结尾的数字是否会超过所给的n。
void solve() {
int k, n;
cin >> k >> n;
int init = 0;
set<int> se;
for (int i = 1; i <= k; i ++) {
init ++;
int t = init + 2, cnt = 3;
for (int j = 1; j <= init; j ++) se.insert(j);
for (int j = 1; j <= k - init; j ++) {
se.insert(t);
t += cnt;
cnt ++;
}
t = t - cnt + 1;
if (t > n) se.clear();
else break;
}
for (auto i : se) cout << i << ' ';
cout << endl;
}
\[\]D - Absolute Sorting
题意:给出序列a,问是否存在一个x,使a中所有元素减去x后的绝对值,形成非严格单调递增的形式。
思路:对相邻两个元素l,r进行观察,如果是递减的,那么res = abs(l - r) + min(l,r)。如果有更大的,则更新。如果是递增的,则判断l,r减去res后的绝对值是否满足条件。如果不满足,则说明不可能同时成立,则输出-1。
对a枚举完后,需再次枚举一遍,观察当前res是否能满足整个序列,如果不能则输出-1
int a[N];
//注意观察N的大小
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
int res = 0;
for (int i = 2; i <= n; i ++) {
if (a[i] - a[i - 1] < 0) {
res = max(res, (a[i - 1] - a[i] + 1) / 2 + a[i]);
}else if (a[i] - a[i - 1] > 0) {
if (abs(a[i] - res) < abs(a[i - 1] - res)) {
cout << -1 << endl;
return ;
}
}else continue;
}
for (int i = 2; i <= n; i ++) {
if (abs(a[i] - res) < abs(a[i - 1] - res)) {
cout << -1 << endl;
return ;
}
}
cout << res << endl;
}
\[\]E - Permutation Game
题意:给出一个含有n个数的排列,当前每个数字都是红色的,两个选手轮流进行三种操作之一:
1.将蓝色元素任意排列
2.将一个红色元素染成蓝色
3.跳过当前回合
如果第一个选手可以将排列变成单调递增的,则他赢
如果第二个选手可以将排列变成单调递减的,则他赢
否则,若两个选手无法决出胜负,则平局
思路:其实就是看谁先能将他所需要元素的涂成蓝色。设第一个选手需要涂得颜色数量为firstone,第二个为secondone,他们两个都需要涂得为both。如果第二个选手只涂他自己要涂的,第一个选手把共同的和他自己的都涂了,此时若第一个选手需要涂得书目小于等于第二个选手,则说明他一定能赢。(等于是因为第一个选手先手)
反之亦然,第二个选手涂得小于第一个选手,则说明他能赢。
否则平局
const int N = 5e5 + 10, M = 5010, INF = 2e9, MOD = 998244353;
int a[N];
//注意观察N的大小
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
int firstone = 0, secondone = 0, both = 0;
for (int i = 1; i <= n; i ++) {
if (a[i] != i) firstone ++;
if (a[i] != n - i + 1) secondone ++;
if (a[i] != i && a[i] != n - i + 1) both ++;
}
if (firstone + both <= secondone) cout << "First" << endl;
else if (secondone + both < firstone) cout << "Second" << endl;
else cout << "Tie" << endl;
}