第十五届蓝桥杯软件赛省赛C/C++B 组题解
目录
试题 A: 握手问题
本题总分:
思路:组合计数,用为
握手问题
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int f[N], n, m; inline void solve() { int ans = 50 * 49 / 2 - 7 * 6 / 2; cout << ans << '\n'; //1204 } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(8); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
答案:
试题 B: 小球反弹
本题总分:
思路:由题意,小球返回原点时,在长和宽两个方向所经历的路程均为长方形的长和宽的偶数倍,推公式 (拒绝玄学,开始推公式),设小球返回原点经历的
得到的
于是有小球每次返回原点,经历两分量的路程及时间:
所经历的总时间及总路程:
将 1100325199.77
小球反弹
#include <bits/stdc++.h> #define int long long #define deb(x) cout << #x << " = " << x << '\n' #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define all1(f) f.begin() + 1, f.end() #define here system("pause") #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define MOD 998244353 #define mod 1000000007 #define endl "\n" #define x first #define y second using namespace std; inline void solve() { int x = 343720, y = 233333, dx = 15, dy = 17; int kx = dx * y, ky = dy * x; int gcd = __gcd(kx, ky); kx /= gcd, ky /= gcd; cout << kx << ' ' << ky << '\n'; double t = 2.0 * kx * x / dx; cout << t << '\n'; double ans = t * sqrt(dx * dx + dy * dy); cout << ans << '\n'; // 1100325199.77 } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; // cin >> _; cout << fixed << setprecision(2); while(_ --) { solve(); } return _ ^ _; }
答案:1100325199.77
试题 C: 好数
时间限制:
思路:暴力枚举 j % 2 == s[s.size() - j - 1] % 2
,若成立则不是好数,统计答案
好数
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int ans, n, m; inline void solve() { cin >> n; for(int i = 1; i <= n; i ++) { string s = to_string(i); bool ok = true; for(int j = 0; j < s.size(); j ++) { if(j % 2 == s[s.size() - j - 1] % 2) { ok = false; break; } } if(ok) { ans ++; } } cout << ans << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(2); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
试题 D: R 格式
时间限制:
思路:用long double
存储答案,先乘以 %.0lf
浮点数默认向最近的整数格式化输出
R 格式
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); db ans, n; int m; inline void solve() { cin >> m >> n; for(int i = 0; i < m; i ++) { n *= 2.0; } cout << n << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(0); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
R 格式(正解高精度)
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 30, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); inline string add(string a, string b) { int f = 0; string ans = ""; if(b == "1") { for(int i = 1; i < a.size(); i ++) { b.push_back('0'); } reverse(all(b)); } for(int i = a.size() - 1; i >= 0; i --) { int v = a[i] - '0' + b[i] - '0' + f; if(v > 9) { v %= 10, f = 1; } else { f = 0; } ans.push_back(v + '0'); } if(f) { ans.push_back('1'); } reverse(all(ans)); return ans; } void solve() { int n, pos = 0; string s; cin >> n >> s; string x = ""; for(int i = 0; i < s.size(); i ++) { if(s[i] == '.') { pos = s.size() - i - 1; break; } } for(auto t : s) { if(t != '.') { x.push_back(t); } } for(int i = 1; i <= n; i ++) { x = add(x, x); } char check = x[x.size() - pos]; string xx = ""; for(int i = 0; i < x.size() - pos; i ++) { xx.push_back(x[i]); } if(check >= '5') { xx = add(xx, "1"); } cout << xx << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(0); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
试题 E: 宝石组合
时间限制:
思路:公式化简后即为求
宝石组合(暴力)
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int n, m, ans; int aa, bb, cc; inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } inline int lcm(int a, int b) { return a * b / gcd(a, b); } inline void solve() { cin >> n; vector<int> f(n); for(int i = 0; i < n; i ++) { cin >> f[i]; } sort(all(f)); for(int i = 0; i < n - 2; i ++) { for(int j = i + 1; j < n - 1; j ++) { for(int k = j + 1; k < n; k ++) { int a = f[i], b = f[j], c = f[k]; int s = a * b * c; int abc = lcm(lcm(a, b), c); int ab = lcm(a, b); int bc = lcm(b, c); int ac = lcm(a, c); if(ab > bc) { swap(ab, bc); } if(bc > ac) { swap(bc, ac); } s = s / ac * abc / ab / bc; if(s > ans) { ans = s; aa = a, bb = b, cc = c; } } } } cout << aa << ' ' << bb << ' ' << cc << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(0); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
宝石组合(正解)
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int f[N]; int n, p, q, ans, mx; inline void solve() { cin >> n; vector<int> f(n), ans; map<int, int> mp; for(int i = 0; i < n; i ++) { cin >> f[i]; } sort(all(f)); for(int i = 0; i < n; i ++) { int t = f[i]; for(int j = 1; j <= t / j; j ++) { if(t % j == 0) { mp[j] ++; if(mp[j] >= 3) { mx = max(mx, j); } if(t / j != j) { mp[t / j] ++; if(mp[t / j] >= 3) { mx = max(mx, t / j); } } } } } for(int i = 0; i < n; i ++) { if(f[i] % mx == 0) { ans.emplace_back(f[i]); } } cout << ans[0] << ' ' << ans[1] << ' ' << ans[2] << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(2); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
试题 F: 数字接龙
时间限制:
思路:下一个点是否可达 + 是否满足取模后升序 + 是否交叉
,后执行递归,递归时传入下一个能到达的点的坐标(x, y) + 当前走的数字a[nx][ny] + 统计的答案tt
,若到达右下角x == n - 1&&y == n - 1
,则判断并更新答案,答案依旧用long double
存,特判答案为-1
的情况,按照这个思路,代码调麻了,特殊情况没有特判完,应该不会全对
数字接龙
#include <bits/stdc++.h> #define int long long #define deb(x) cout << #x << " = " << x << '\n' #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define all1(f) f.begin() + 1, f.end() #define here system("pause") #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define MOD 998244353 #define mod 1000000007 #define endl "\n" #define x first #define y second #ifdef LOCAL #include "algo/debug.h" #else #define dbg(...) "cyh2.2" #define debug(...) "cyh2.2" #endif using namespace std; template <class T> inline void read(T& x) {x = 0;char c = getchar();bool f = 0;for(; !isdigit(c); c = getchar()) f ^= (c == '-'); for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); x = f ? -x : x; } template <class T> inline void write(T x) {if(x < 0) putchar('-'), x = -x;if(x < 10) putchar(x + 48);else write(x / 10), putchar(x % 10 + 48); } inline int qmi(int a, int b, int p) {int ans = 1 % p;while(b){if(b & 1) ans = ans * a % p;a = a * a % p;b >>= 1;} return ans;} inline int inv(int a, int p) {return qmi(a, p - 2, p) % p;} const int N = 2e5 + 10, M = 150, maxn = 20; const double pi = acos(-1); const long double E = exp(1); const double eps = 1e-8; typedef pair<int, int> pii; int a[M][M]; int ne[8][2] = {-1, 0, -1, 1, 0, 1, 1, 1, 1, 0, 1, -1, 0, -1, -1, -1}; int n, m; double ans; bool st[M][M]; inline void dfs(int x, int y, int t, double tt) { if(x == n - 1&&y == n - 1) { string s = to_string(tt); int x = 0; for(int i = 0; i < s.size(); i ++) { if(s[i] == '.') { x = i; } } if(x == n * n - 1) { ans = min(ans, tt); } //cout << tt << ' '; return; } for(int i = 0; i < 8; i ++) { int nx = x + ne[i][0]; int ny = y + ne[i][1]; if(nx >= 0&&nx < n&&ny >= 0&&ny < n&&!st[nx][ny]&&((t == m - 1&&a[nx][ny] == 0)||(t < m - 1&&a[nx][ny] == t + 1))) { bool ok = true; if(st[nx][y]&&st[x][ny]) { ok = false; } if(ok) { st[nx][ny] = true; dfs(nx, ny, a[nx][ny], tt * 10 + i); st[nx][ny] = false; } } } } inline void solve() { ans = 1e27; cin >> n >> m; for(int i = 0; i < n; i ++) { for(int j = 0; j < n; j ++) { cin >> a[i][j]; } } if(a[0][0]) { cout << -1 << '\n'; return ; } st[0][0] = true; dfs(0, 0, 0, 0); if(ans > 1e26) { ans = -1; } cout << ans << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; // cin >> _; cout << fixed << setprecision(0); while(_ --) { solve(); } return _ ^ _; }
数字接龙(正解)
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 30, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int n, k; int qx = 0, qy = 0, zx, zy; int g[N][N], f[N][N], fx[N][N], bu[N * N]; int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}; int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1}; int res = 0; void otto() { for (int i = 0; i < n * n - 1; ++i) cout << bu[i]; } void dfs(int x, int y, int bus, int zt) { //已经找到结果了,不找了 if (res == 1) return; //坐标正确,步数正确,允许输出 if (x == zx && y == zy && bus == n * n - 1) { //标记为找到 res = 1; //调用函数把结果打出来 otto(); return; } //循环走方格 if (zt == k - 1) zt = -1; //八个方向,顺时针就不用管字典序 for (int i = 0; i < 8; ++i) { //一个新的点的俩坐标 int vx = x + dx[i]; int vy = y + dy[i]; //标记 错号 出界 if (f[vx][vy] || g[vx][vy] != zt + 1 || x < 0 || y < 0 || x >= n || y >= n) continue; //如果会交叉 if (i == 1 && (fx[x][y + 1] == 7 || fx[x - 1][y] == 3)) continue; if (i == 3 && (fx[x][y + 1] == 5 || fx[x + 1][y] == 1)) continue; if (i == 5 && (fx[x][y - 1] == 3 || fx[x + 1][y] == 7)) continue; if (i == 7 && (fx[x][y - 1] == 1 || fx[x - 1][y] == 5)) continue; //开搜 f[vx][vy] = 1; fx[x][y] = i; bu[bus] = i; dfs(vx, vy, bus + 1, g[vx][vy]); bu[bus] = -1; fx[x][y] = -1; f[vx][vy] = 0; } } inline void solve() { //初始化一些数据 memset(fx, -1, sizeof fx); memset(f, 0, sizeof f); memset(bu, -1, sizeof bu); //输入 cin >> n >> k; zx = n - 1, zy = n - 1; for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { cin >> g[i][j]; } } //起点标成走过 f[qx][qy] = 1; //我搜搜搜 dfs(qx, qy, 0, 0); //没找到 if (!res) { cout << -1 << endl; } } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(0); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
试题 G: 爬山
时间限制:
思路:优先队列 + 贪心,用大根堆存储山的高度
有网友说大根堆+贪心
容易被 Hack
,后面官方题解也是用的这个思路,没办法,再拭目以待吧
爬山
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int f[N]; int n, p, q, ans; inline void solve() { cin >> n >> p >> q; priority_queue<int, vector<int>, less<int> > qq; for(int i = 1; i <= n; i ++) { cin >> f[i]; qq.push(f[i]); } while(q||p) { int x = qq.top(); qq.pop(); int t = x, a = x, b = x; if(p > 0) { a = sqrt(x); } if(q > 0) { b = x / 2; } if(a <= b&&p > 0) { t = a; p --; } else if(q > 0) { t = b; q --; } qq.push(t); } while(qq.size()) { int x = qq.top(); qq.pop(); ans += x; } cout << ans << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(2); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
试题 H: 拔河
时间限制:
思路:赛时看数据范围+样例说明
后直接前缀和 - 后缀和
出结果,但数据不一定保证两组成员人数之和必为 前缀和 + 二维二分
暴力,但边界情况得处理好,不然也是容易被Hack
拔河
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 2e5 + 10, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); int f[N], f1[N], f2[N]; int n, ans; inline void solve() { cin >> n, ans = 1e18; for(int i = 1; i <= n; i ++) { cin >> f[i]; f1[i] = f1[i - 1] + f[i]; } for(int i = n; i >= 1; i --) { f2[i] = f2[i + 1] + f[i]; } for(int i = 1; i <= n; i ++) { ans = min(ans, abs(f2[i] - f1[i - 1])); } cout << ans << '\n'; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(2); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
拔河(正解)
#include <bits/stdc++.h> #define int long long #define db long double #define all(f) f.begin(), f.end() #define rall(f) f.rbegin(), f.rend() #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define mod 1000000007 #define MOD 998244353 #define x first #define y second using namespace std; const int N = 30, M = 1010, S = 25; typedef pair<int, int> pii; const db eps = 1e-8; const db pi = acos(-1); void solve() { int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i ++ ) { cin >> a[i]; a[i] += a[i - 1]; } map<int, int> pre; for (int i = 1; i <= n; i ++ ) { for (int j = i; j <= n; j ++ ) { pre[a[j] - a[i - 1]] += 1; } } int ans = 1E18; for (int i = n; i >= 2; i -- ) { for (int j = 1; j <= i; j ++ ) { int v = a[i] - a[j - 1]; pre[v] --; if (pre[v] == 0) { pre.erase(v); } } for (int j = i; j <= n; j ++ ) { int v = a[j] - a[i - 1]; auto t = pre.lower_bound(v); if (t != pre.end()) { ans = min(ans, t->first - v); } t = pre.upper_bound(v); if (t != pre.begin()) { --t; ans = min(ans, v - t->first); } } } cout << ans << "\n"; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr), cout.tie(nullptr); int _ = 1; cout << fixed << setprecision(0); // cin >> _; while(_ --) { solve(); } return _ ^ _; }
本文作者:chfychin
本文链接:https://www.cnblogs.com/chfychin/p/18133301
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步