本文主要是介绍2024.2.29 训练记录(4),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- CF 1933F Turtle Mission: Robot and the Earthquake
- CF 1933G Turtle Magic: Royal Turtle Shell Pattern
- CF 1826D Running Miles
- CF 1820D The Butcher
- CF 1768C Elemental Decompress
CF 1933F Turtle Mission: Robot and the Earthquake
题目链接
bfs,把图当做不动的,那么往下走就相当于往下两步,往右走就相当于往右下方走,往上走就相当于不动,当走到最后一列的时候再计算走到终点需要多少步(每走一步终点的相对位置都下移一格,根据走的步数可以推断人在最后一列时终点在哪一行)
debug里发现的一个易错点是:更新st数组的时候要在距离改变了之后再更新,距离没改变就不更新!!!
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;int dx[] = {1, 2, 0}, dy[] = {1, 0, 0};void solve()
{int n, m;cin >> n >> m;vector<vector<int>> g(n, vector<int>(m));for (int i = 0; i < n; i ++ )for (int j = 0; j < m; j ++ )cin >> g[i][j];queue<PIII> q;q.push({0, {0, 0}});vector<vector<int>> dist(n, vector<int>(m, INF));vector<vector<bool>> st(n, vector<bool>(m));st[0][0] = true;dist[0][0] = 0;int ans = INF;while (q.size()){auto t = q.front();q.pop();int x = t.second.first, y = t.second.second, d = t.first;if (y == m - 1){int end = (n - 1 + d) % n;if (end == x) ans = min(ans, dist[x][y]);else if (end > x) ans = min(ans, dist[x][y] + min(end - x, n - (end - x)));else ans = min(ans, dist[x][y] + min(x - end, n - (x - end)));continue;}for (int i = 0; i < 3; i ++ ){int nx = (x + dx[i]) % n, ny = y + dy[i];if (ny >= m) continue;if (st[nx][ny]) continue;if (i == 0){if (g[nx][ny] == 1) continue;if (dist[nx][ny] > d + 1){st[nx][ny] = true;dist[nx][ny] = d + 1;q.push({d + 1, {nx, ny}});}}else if (i == 1){if ((x == n - 1 && (g[0][y] == 1 || g[1][y] == 1)) || (x == n - 2 && (g[n - 1][y] == 1 || g[0][y] == 1)) || (x != n - 1 && x != n - 2 && (g[x + 1][y] == 1 || g[x + 2][y] == 1))) continue;if (dist[nx][ny] > d + 1){st[nx][ny] = true;dist[nx][ny] = d + 1;q.push({d + 1, {nx, ny}});}}else if (i == 2){if (dist[nx][ny] > dist[x][y] + 1){st[nx][ny] = true;dist[nx][ny] = dist[x][y] + 1;q.push({d + 1, {nx, ny}});}}}}if (ans != INF) cout << ans << '\n';else cout << -1 << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
CF 1933G Turtle Magic: Royal Turtle Shell Pattern
题目链接
又是喜闻乐见的找规律…
首先可以证明一定是两个两个连在一起(反证法画一下图就好了),就像是这样(下面这个例子是行的,列也可以)
xxoox
ooxxo
xxoox
ooxxo
所以最多只会有八种情况(行和列各四种),取模鉴定为诈骗
所以每添加一个直接判断会不会让哪一种情况无了就可以
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{// circle为0 square为1int n, m, q;cin >> n >> m >> q;cout << 8 << '\n';int ans = 8;vector<bool> st(9);while (q -- ){int a, b;string s;cin >> a >> b >> s;for (int i = 1; i < 9; i ++ ){if (st[i]) continue;if (i == 1){if (a % 2 == 1 && (b + 1) / 2 % 2 == 0 && s[0] == 'c') continue;else if (a % 2 == 1 && (b + 1) / 2 % 2 != 0 && s[0] == 's') continue;else if (a % 2 == 0 && (b + 1) / 2 % 2 == 0 && s[0] == 's') continue;else if (a % 2 == 0 && (b + 1) / 2 % 2 != 0 && s[0] == 'c') continue;else st[i] = true, ans -- ;}else if (i == 2){if (a % 2 == 1 && (b + 1) / 2 % 2 == 0 && s[0] == 's') continue;else if (a % 2 == 1 && (b + 1) / 2 % 2 != 0 && s[0] == 'c') continue;else if (a % 2 == 0 && (b + 1) / 2 % 2 == 0 && s[0] == 'c') continue;else if (a % 2 == 0 && (b + 1) / 2 % 2 != 0 && s[0] == 's') continue;else st[i] = true, ans -- ;}else if (i == 3){if (a % 2 == 1 && b / 2 % 2 == 0 && s[0] == 's') continue;else if (a % 2 == 1 && b / 2 % 2 != 0 && s[0] == 'c') continue;else if (a % 2 == 0 && b / 2 % 2 == 0 && s[0] == 'c') continue;else if (a % 2 == 0 && b / 2 % 2 != 0 && s[0] == 's') continue;else st[i] = true, ans -- ;}else if (i == 4){if (a % 2 == 1 && b / 2 % 2 == 0 && s[0] == 'c') continue;else if (a % 2 == 1 && b / 2 % 2 != 0 && s[0] == 's') continue;else if (a % 2 == 0 && b / 2 % 2 == 0 && s[0] == 's') continue;else if (a % 2 == 0 && b / 2 % 2 != 0 && s[0] == 'c') continue;else st[i] = true, ans -- ;}else if (i == 5){if (b % 2 == 1 && (a + 1) / 2 % 2 == 1 && s[0] == 's') continue;else if (b % 2 == 1 && (a + 1) / 2 % 2 == 0 && s[0] == 'c') continue;else if (b % 2 == 0 && (a + 1) / 2 % 2 == 1 && s[0] == 'c') continue;else if (b % 2 == 0 && (a + 1) / 2 % 2 == 0 && s[0] == 's') continue;else st[i] = true, ans -- ;}else if (i == 6){if (b % 2 == 1 && (a + 1) / 2 % 2 == 1 && s[0] == 'c') continue;else if (b % 2 == 1 && (a + 1) / 2 % 2 == 0 && s[0] == 's') continue;else if (b % 2 == 0 && (a + 1) / 2 % 2 == 1 && s[0] == 's') continue;else if (b % 2 == 0 && (a + 1) / 2 % 2 == 0 && s[0] == 'c') continue;else st[i] = true, ans -- ;}else if (i == 7){if (b % 2 == 1 && a / 2 % 2 == 1 && s[0] == 's') continue;else if (b % 2 == 1 && a / 2 % 2 == 0 && s[0] == 'c') continue;else if (b % 2 == 0 && a / 2 % 2 == 1 && s[0] == 'c') continue;else if (b % 2 == 0 && a / 2 % 2 == 0 && s[0] == 's') continue;else st[i] = true, ans -- ;}else if (i == 8){if (b % 2 == 1 && a / 2 % 2 == 1 && s[0] == 'c') continue;else if (b % 2 == 1 && a / 2 % 2 == 0 && s[0] == 's') continue;else if (b % 2 == 0 && a / 2 % 2 == 1 && s[0] == 's') continue;else if (b % 2 == 0 && a / 2 % 2 == 0 && s[0] == 'c') continue;else st[i] = true, ans -- ;}}cout << ans << '\n';}
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
CF 1826D Running Miles
题目链接
一开始以为是区间dp,然后发现数据范围根本不能开二维数组qwq
题目要求 a[l] + a[k] + a[r] - (r - l)
转化一下 a[l] + l + a[k] + a[r] - r
处理一下 a[i] + i
和 a[i] - i
,再枚举 k 就行了
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n;cin >> n;vector<int> a(n + 1);for (int i = 1; i <= n; i ++ ) cin >> a[i];vector<int> b(n + 1), c(n + 1);for (int i = 1; i <= n; i ++ ){b[i] = a[i] + i;c[i] = a[i] - i;}vector<int> maxb(n + 1), maxc(n + 1);int tmp1 = b[1], tmp2 = c[n];for (int i = 2; i <= n; i ++ ){maxb[i] = tmp1;tmp1 = max(tmp1, b[i]);}for (int i = n - 1; i >= 1; i -- ){maxc[i] = tmp2;tmp2 = max(tmp2, c[i]);}int ans = 0;for (int i = 2; i <= n - 1; i ++ ){ans = max(ans, a[i] + maxb[i] + maxc[i]);}cout << ans << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
CF 1820D The Butcher
题目链接
这一题首先要想到,切第一刀的时候,切下来不动的那一块,要不长和原矩形相等,要不宽和原矩形相等,所以两种情况都判断一下
想到这一点之后还会因为实现方式被卡:如果横着切,也就是长不动,那就把所有长等于最大值的都删掉,宽里删掉相应的边,竖着切相反
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;void solve()
{int n;cin >> n;map<int, multiset<int>> xx, yy;int s = 0;int maxx = 0, maxy = 0;for (int i = 0; i < n; i ++ ){int x, y;cin >> x >> y;maxx = max(maxx, x);maxy = max(maxy, y);xx[x].insert(y);yy[y].insert(x);s += x * y;}function<bool(int, int, int, map<int, multiset<int>>, map<int, multiset<int>>)> check = [&](int a, int b, int idx, map<int, multiset<int>> xx, map<int, multiset<int>> yy){int tmp = n;while (a > 0 && b > 0){int tt = tmp;if (idx == 1) // 横不动{for (auto t : xx[a]){b -= t;yy[t].erase(yy[t].find(a));tmp -- ;}xx.erase(a);idx ^= 1;}else if (idx == 0) // 竖不动{for (auto t : yy[b]){a -= t;xx[t].erase(xx[t].find(b));tmp -- ;}yy.erase(b);idx ^= 1;}if (tmp == tt) return false;}return true;};set<PII> ans;if (s % maxx == 0 && check(maxx, s / maxx, 1, xx, yy))ans.insert({maxx, s / maxx});if (s % maxy == 0 && check(s / maxy, maxy, 0, xx, yy))ans.insert({s / maxy, maxy});cout << ans.size() << '\n';for (auto t : ans)cout << t.first << ' ' << t.second << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
CF 1768C Elemental Decompress
题目链接
从小到大,每次贪心取数,不能取到合法数字就no
#include <bits/stdc++.h>using namespace std;#define int long long
using i64 = long long;typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;const int N = 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;bool cmp(PII a, PII b)
{return a.second < b.second;
}void solve()
{int n;cin >> n;vector<PII> a(n);for (int i = 0; i < n; i ++ ){cin >> a[i].first;a[i].second = i;}sort(a.begin(), a.end());set<int> stp, stq;for (int i = 1; i <= n; i ++ ){stp.insert(i);stq.insert(i);}vector<PII> p(n), q(n);for (int i = 0; i < n; i ++ ){int x = a[i].first;p[i].second = a[i].second;q[i].second = a[i].second;int it;if (stp.find(x) != stp.end()){p[i].first = x;stp.erase(x);for (auto t : stq){it = t;break;}if (it > x){cout << "NO\n";return;}stq.erase(it);q[i].first = it;}else if (stq.find(x) != stq.end()){q[i].first = x;stq.erase(x);for (auto t : stp){it = t;break;}if (it > x){cout << "NO\n";return;}stp.erase(it);p[i].first = it;}else{cout << "NO\n";return;}}sort(p.begin(), p.end(), cmp);sort(q.begin(), q.end(), cmp);cout << "YES\n";for (auto t : p) cout << t.first << ' ';cout << '\n';for (auto t : q) cout << t.first << ' ';cout << '\n';
}signed main()
{ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t -- ){solve();}
}
这篇关于2024.2.29 训练记录(4)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!