A. Jelly
Solution
之前的牛客小白赛做过, 然后一点开代码就在上面了(于是8秒ac了
就是个三维bfs的裸题而已
Code
#include<bits/stdc++.h> #define endl '\n' using namespace std; typedef unsigned long long ll; static auto faster_iostream = []() { std::ios::sync_with_stdio(false); // turn off sync std::cin.tie(nullptr); // untie in/out streams return 0; }(); const int N = 2e5 + 5; const int mod = 20010905; struct node{ int x, y, z; int step; node(int _x = 0, int _y = 0, int _z = 0, int _step = 0):x(_x), y(_y), z(_z), step(_step){} }; int dist[6][3] = {1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1}; char maze[105][105][105]; bool vis[105][105][105]; int n; int bfs(int x, int y, int z){ queue<node>q; q.push(node(x, y, z, 1)); while(!q.empty()){ node now = q.front(); q.pop(); if(now.x == n && now.y == n && now.z == n){ return now.step; } for(int i = 0; i < 6; i++){ int xx = now.x + dist[i][0]; int yy = now.y + dist[i][1]; int zz = now.z + dist[i][2]; if(!vis[xx][yy][zz] && maze[xx][yy][zz] == '.'){ vis[xx][yy][zz] = 1; q.push(node(xx, yy, zz, now.step + 1)); } } } return -1; } int main(){ cin >> n; for(int i = 1; i <= n; i++){ for(int j = 1; j <= n; j++){ for(int k = 1; k <= n; k++){ cin >> maze[i][j][k]; } } } vis[1][1][1] = 1; cout << bfs(1, 1, 1) << endl; }
B. 「木」迷雾森林
Solution
我的做法是记忆化搜索, 用dp[x][y] 表示 x行 y列到达右上角的方案数, 直接搜索即可
Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long long LL; const int N = 5e6 + 5; const ll mod = 2333; const int DEG = 30; const double PI = acos(-1.0); const double eps = 1e-12; const ll inf = 1e18; static auto faster_iostream = []() { std::ios::sync_with_stdio(false); // turn off sync std::cin.tie(nullptr); // untie in/out streams return 0; }(); template<class T>inline void redi(T &res) { char c;T flag=1; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; } int dist[2][2] = {-1, 0, 0, 1}; int n, m; int dp[3005][3005]; int maze[3005][3005]; int dfs(int x, int y){ //cout << x << ' ' << y << "\n"; if(x <= 0 || x > n || y <= 0 || y > m || maze[x][y] == 1) return 0; if(dp[x][y] != -1) return dp[x][y]; if(x == 1 && y == m) return 1; ll ans = 0; for(int i = 0; i < 2; i++){ ans += dfs(x + dist[i][0], y + dist[i][1]); ans %= mod; } return dp[x][y] = ans % mod; } int main(){ redi(n), redi(m); for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ redi(maze[i][j]); } } memset(dp, -1, sizeof(dp)); dfs(n, 1); // for(int i = 1; i <= n; i++) { // for(int j = 1; j <= m; j++){ // cout << dp[i][j] << " \n"[j == m]; // } // } printf("%d\n", dp[n][1]); return 0; }
C. 小雨坐地铁
Solution
分层图最短路, 也是某个小白月赛的题, 做了一个多小时orz
每条地铁线看做是一层图
我的做法是把对每个车站建立一个超级源点, 车站到超级源点的花费是0, 源点往车站的花费是上/转地铁的花费
最后跑一遍Dijkstra 找超级源点s到超级源点t的最短路
样例图是这样的(红色的是超级源点):
从超级源点1 -> 1 -> 3 -> 超级源点3 -> 另一层线路的3 -> 4
总花费为 2 + 2 + 2 + 1 = 7
Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long long LL; const int N = 2e6 + 5; const ll mod = 2333; const int DEG = 30; const double PI = acos(-1.0); const double eps = 1e-12; const ll inf = 1e18; static auto faster_iostream = []() { std::ios::sync_with_stdio(false); // turn off sync std::cin.tie(nullptr); // untie in/out streams return 0; }(); int a[N], b[N]; struct Edge { int v, nextz; ll w; }edge[N << 1]; int tot, head[N]; struct qnode { int v; ll cost; qnode(int _v = 0, ll _cost = 0): v(_v), cost(_cost) {} bool operator < (const qnode &s)const { return cost > s.cost; } }; void addedge(int u, int v, ll w) { edge[tot].v = v; edge[tot].w = w; edge[tot].nextz = head[u]; head[u] = tot++; } ll dist[N]; bool vis[N]; void Dijkstra(int start) { for(int i = 1; i <= 1e6; i++) dist[i] = inf; priority_queue<qnode> q; q.push(qnode(start, 0)); dist[start] = 0; while(!q.empty()) { qnode tmp = q.top(); q.pop(); int u = tmp.v; if(vis[u]) continue; vis[u] = 1; for(int i = head[u]; ~i; i = edge[i].nextz) { ll cost = edge[i].w; int v = edge[i].v; if(!vis[v] && dist[v] > dist[u] + cost) { dist[v] = dist[u] + cost; q.push(qnode(v, dist[v])); } } } } int main() { memset(head, -1, sizeof(head)); int n, m, s, t; cin >> n >> m >> s >> t; for(int i = 1; i <= m; i++) { int num; cin >> a[i] >> b[i] >> num; int x = 0, last = 0; for(int j = 1; j <= num; j++) { cin >> x; if(j != 1) { addedge((i - 1) * n + x, (i - 1) * n + last, b[i]); addedge((i - 1) * n + last, (i - 1) * n + x, b[i]); } addedge((i - 1) * n + x, (m + 1) * n + x, 0); addedge((m + 1) * n + x, (i - 1) * n + x, a[i]); last = x; } } Dijkstra((m + 1) * n + s); cout << (dist[(m + 1) * n + t] >= inf ? -1 : dist[(m + 1) * n + t]) << "\n"; return 0; }
D. 表达式求值
Solution
因为只有乘和加, 我们考虑先做乘法, 剩下的数字存到一个栈里, 最后栈里肯定都是做加法运算的
直接加完即可
因为只保留后面四位, 要模个1e4
Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long long LL; const int N = 5e6 + 5; const ll mod = 2333; const int DEG = 30; const double PI = acos(-1.0); const double eps = 1e-12; const ll inf = 1e18; static auto faster_iostream = []() { std::ios::sync_with_stdio(false); // turn off sync std::cin.tie(nullptr); // untie in/out streams return 0; }(); int main(){ string s; cin >> s; stack<int> st; for(int i = 0; i < s.size(); ) { if(isdigit(s[i])) { ll res = 0; while(isdigit(s[i])) { res = res * 10 + s[i] - '0'; res %= 10000; i++; } st.push(res); } else if(s[i] == '*') { ll p = 0; i++; while(isdigit(s[i])) { p = p * 10 + s[i] - '0'; p %= 10000; i++; } int last = st.top(); st.pop(); st.push(last * p % 10000); } else if(s[i] == '+') { i++; } } while(st.size() >= 2) { int p1 = st.top(); st.pop(); int p2 = st.top(); st.pop(); st.push((p1 + p2) % 10000); } cout << st.top() % 10000 << "\n"; return 0; }
E Sunscreen
Solution
一道贪心题
题意 c只牛, l种防晒, 每种牛有一个舒适范围, 防晒能够让牛位于某个值SPF, 但有数量限制
做法是贪心
把牛按区间右端点排序, 把防晒按SPF值排序, 因为数据范围很小
找到剩余防晒中第一个能让牛位于舒适区的防晒即可
看了眼数据范围, 直接解决即可
Code
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long long LL; const int N = 1e6 + 5; const ll mod = 2333; const int DEG = 30; const double PI = acos(-1.0); const double eps = 1e-12; const ll inf = 1e18; static auto faster_iostream = []() { std::ios::sync_with_stdio(false); // turn off sync std::cin.tie(nullptr); // untie in/out streams return 0; }(); struct cow { int l, r; }C[N]; struct lu { int p, num; }L[N]; int main() { int c, l; cin >> c >> l; for(int i = 1; i <= c; i++) { cin >> C[i].l >> C[i].r; } for(int i = 1; i <= l; i++) { cin >> L[i].p >> L[i].num; } sort(L + 1, L + 1 + l, [](const lu &x, const lu &y){return x.p < y.p;}); sort(C + 1, C + 1 + c, [](const cow &x, const cow &y){return x.r < y.r;}); int ans = 0; for(int i = 1; i <= c; i++) { for(int j = 1; j <= l; j++) { if(L[j].p >= C[i].l && L[j].p <= C[i].r && L[j].num) { L[j].num--; ans++; break; } } } cout << ans << "\n"; return 0; }