A. Reverse
思路
签到
#include <bits/stdc++.h>
using namespace std;
const int N = 5e3 + 10;
int a[N], b[N];
int main() {
int t;
scanf("%d", &t);
while (t -- ) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) {
scanf("%d", a + i);
b[i] = a[i];
}
sort(b + 1, b + 1 + n);
int pos = 0;
for (int i = 1; i <= n; i ++ )
if (b[i] != a[i]) {
pos = i;
break;
}
if (pos == 0) {
for (int i = 1; i <= n; i ++ )
printf("%d ", a[i]);
puts("");
continue;
}
int ed;
for (int i = 1; i <= n; i ++ )
if (a[i] == b[pos]) {
ed = i;
break;
}
for (int i = pos; i <= (pos + ed) / 2; i ++ )
swap(a[i], a[ed - (i - pos)]);
for (int i = 1; i <= n; i ++ )
printf("%d ", a[i]);
puts("");
}
return 0;
}
B. Odd Swap Sort
思路
N o No No 的条件是,大奇数要跨越小奇数,大偶数要跨越小偶数。剩下的都是 Y e s Yes Yes
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int sum[N];
struct Node{
int a, id;
int odd, even;
}num[N];
bool cmp(Node a, Node b) {
if (a.a != b.a) return a.a < b.a;
else return a.id < b.id;
}
int main() {
int t;
scanf("%d", &t);
while (t -- ) {
int n;
scanf("%d", &n);
bool ok = 1;
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &num[i].a);
num[i].id = i;
if (num[i].a & 1) {
if (num[i - 1].odd > num[i].a) ok = 0;
num[i].odd = max(num[i - 1].odd, num[i].a);
num[i].even = num[i - 1].even;
} else {
if (num[i - 1].even > num[i].a) ok = 0;
num[i].even = max(num[i - 1].even, num[i].a);
num[i].odd = num[i - 1].odd;
}
}
if (ok) puts("Yes");
else puts("No");
}
return 0;
}
C. Inversion Graph
思路
显然这和图论并查集没有关系,并查集必然
T
L
E
TLE
TLE
那换个思路,题目考查连通块,看到样例解释的图,容易想到区间合并
#include <bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define MP make_pair
#define PB push_back
typedef pair<int, int> PII;
const int N = 1e5 + 10;
struct Node{
int a, id;
int f;
}num[N];
bool cmp(Node a, Node b) {
return a.a < b.a;
}
int cnt;
vector<PII> seg;
void work() {
sort(seg.begin(), seg.end());
int ed = -2e9;
for (auto t : seg) {
if (ed < t.FI) cnt ++;
ed = max(ed, t.SE);
}
}
int main() {
int t;
scanf("%d", &t);
while (t -- ) {
int n;
scanf("%d", &n);
cnt = 0;
seg.clear();
for (int i = 1; i <= n; i ++ ) {
scanf("%d", &num[i].a);
num[i].id = i;
}
sort(num + 1, num + n + 1, cmp);
for (int i = 1; i <= n; i ++ )
num[i].f = i;
for (int i = 1; i <= n; i ++ ) {
seg.PB(minmax(num[i].f, num[i].id));
}
work();
cout << cnt << endl;
}
return 0;
}
D. Big Brush
思路
B
F
S
BFS
BFS(
D
F
S
DFS
DFS 也行)
倒着跑,把一个个能删的块删掉
这题主要是细节吧,还有就是码力了,我写的比较复杂,应该有更好的,如果明天醒来还记得就接着写
#include <bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define MP make_pair
#define PB push_back
typedef pair<int, int> PII;
const int N = 1e3 + 10;
int g[N][N];
struct Res{
int x, y, c;
};
vector<Res> ans;
int n, m;
int check(int x, int y) {
VI tmp;
if (g[x][y]) tmp.PB(g[x][y]);
if (g[x + 1][y]) tmp.PB(g[x + 1][y]);
if (g[x][y + 1]) tmp.PB(g[x][y + 1]);
if (g[x + 1][y + 1]) tmp.PB(g[x + 1][y + 1]);
if (tmp.size() == 0) return 0;
for (int i = 1; i < tmp.size(); i ++ )
if (tmp[i] != tmp[i - 1]) return 0;
return tmp.size();
}
void change(int x, int y) {
g[x][y] = g[x + 1][y] = g[x][y + 1] = g[x + 1][y + 1] = 0;
}
bool cmp(Res a, Res b) {
return a.c > b.c;
}
void bfs(int u, int v) {
queue<PII> q;
q.push(MP(u, v));
while (q.size()) {
int x = q.front().FI, y = q.front().SE;
q.pop();
vector<Res> tmp;
for (int i = -2; i < 4; i ++ ) {
for (int j = -2; j < 4; j ++ ) {
int a = x + i, b = y + j;
if (a < 1 || a > n - 1 || b < 1 || b > m - 1) continue;
int cnt = check(a, b);
if (cnt) {
q.push(MP(a, b));
tmp.PB({a, b, cnt});
}
}
}
sort(tmp.begin(), tmp.end(), cmp);
for (int i = 0; i < tmp.size(); i ++ ) {
int x = tmp[i].x, y = tmp[i].y;
int cnt = check(x, y);
if (cnt) {
ans.PB({x, y, max(g[x][y], max(g[x + 1][y], max(g[x][y + 1], g[x + 1][y + 1])))});
change(x, y);
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
ans.clear();
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
scanf("%d", &g[i][j]);
int x = 0, y = 0;
for (int i = 1; i < n; i ++ )
for (int j = 1; j < m; j ++ ) {
if (check(i, j)) {
x = i, y = j;
break;
}
}
if (x == 0) {
puts("-1");
return 0;
}
bfs(x, y);
bool ok = 1;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
if (g[i][j]) {
ok = 0;
break;
}
if (!ok) {
puts("-1");
return 0;
}
printf("%d\n", ans.size());
for (int i = ans.size() - 1; i >= 0; i -- ) {
printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].c);
}
return 0;
}