欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > c/c++ >内容正文

c/c++

第十二届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学B组

发布时间:2025/3/19 c/c++ 38 豆豆
生活随笔 收集整理的这篇文章主要介绍了 第十二届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学B组 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

试题A :取余

1

试题 B: 双阶乘

// 59375 #include <iostream> using namespace std;const int mod = 100000;int main() {int n = 2021;int res = 1;for (int i = 1; i <= 2021; i += 2) {res = (res * i) % mod;}cout << res; }

试题 C: 格点

// 15698 #include <iostream> using namespace std;int main() {int cnt = 0;for (int i = 1; i <= 2021; ++ i) {for (int j = 1; j <= 2021; ++ j) {if (i * j == 2021)cnt ++ ;}}cout << cnt; }

试题 D: 整数分解

  • dp
  • f[i][j]f[i][j]f[i][j]表示用i个数相加表示数字j的方案数
// 691677274345 #include <iostream> #include <cstring> using namespace std;typedef long long ll;ll f[10][2030];int main() {f[0][0] = 1;for (int i = 1; i <= 5; ++ i) {for (int j = 1; j <= 2021; ++ j) {for (int k = 1; k <= 2021; ++ k) {if (j >= k) f[i][j] += f[i - 1][j - k];}}}cout << f[5][2021]; }
  • 数论隔板法
  • 将2021拆分成2021个1,期间可以放2020个搁板,将2021分成五个正整数相加,也就是在这2020个搁板中选四个位置放四个搁板,因此,答案就是C20204C^4_{2020}C20204
#include <iostream> #include <cstring> using namespace std; typedef long long ll;int main() {ll fenmu = 4 * 3 * 2;ll fenzi = 1;for (int i = 2020; i >= 2017; -- i)fenzi *= i;cout << fenzi / fenmu; }

试题 E: 城邦

  • prim
// 4046 #include <iostream> #include <cstring> using namespace std; typedef long long ll;int dist[2030]; int g[2030][2030]; bool st[2030];int calc(int x, int y) {int a[5], b[5];for (int i = 0; i < 4; ++ i) {a[i] = x % 10;b[i] = y % 10;x /= 10, y /= 10;}int res = 0;for (int i = 0; i < 4; ++ i) {if (a[i] != b[i])res += a[i] + b[i];}return res; } int prim() {memset(dist, 0x3f, sizeof dist);int res = 0;dist[1] = 0;for (int i = 0; i < 2021; ++ i) {int t = -1;for (int j = 1; j <= 2021; ++ j) {if (!st[j] && (t == -1 || dist[j] < dist[t])) {t = j;}}st[t] = true;res += dist[t];for (int j = 1; j <= 2021; ++ j)dist[j] = min(dist[j], g[t][j]);}return res; }int main() {for (int i = 1; i <= 2021; ++ i) {for (int j = 1; j <= 2021; ++ j) {if (i == j) g[i][j] = g[j][i] = 0x3f3f3f3f;g[i][j] = g[j][i] = calc(i, j);}}cout << prim(); }
  • kruscal
#include <iostream> #include <algorithm> using namespace std;const int N = 2021 * 2021 + 10, M = 2021 + 10;struct Edge {int a, b, w;bool operator< (Edge const&e) const {return w < e.w;} }e[N]; int cnt = 0; int p[M];int calc(int x, int y) {int a[5], b[5];for (int i = 0; i < 4; ++ i) {a[i] = x % 10;b[i] = y % 10;x /= 10, y /= 10;}int res = 0;for (int i = 0; i < 4; ++ i) {if (a[i] != b[i])res += a[i] + b[i];}return res; } int find(int x) {if (p[x] != x) p[x] = find(p[x]);return p[x]; } int kruscal() {int res = 0;for (int i = 1; i <= 2021; ++ i)p[i] = i;for (int i = 0; i < cnt; ++ i) {int a = e[i].a, b = e[i].b, w = e[i].w;a = find(a);b = find(b);if (a == b) continue;res += w;p[a] = b;}return res; } int main() {for (int i = 1; i <= 2021; ++ i) {for (int j = 1; j <= 2021; ++ j) {e[cnt ++ ] = {i, j, calc(i, j)};}}sort(e, e + cnt);cout << kruscal(); }

试题 F: 特殊年份

#include <iostream> using namespace std;bool check(int x) {int a[5];for (int i = 0; i < 4; ++ i) {a[i] = x % 10;x /= 10;}if (a[1] == a[3] && a[0] - 1 == a[2]) return true;return false; }int main() {int cnt = 0;for (int i = 0; i < 5; ++ i) {int year;cin >> year;if (check(year))cnt ++ ;}cout << cnt; }

试题 G: 小平方

#include <iostream> using namespace std;int main() {int n;cin >> n;int cnt = 0;for (int i = 1; i <= n - 1; ++ i) {int pf = i * i;if (pf % n < n / 2.0)cnt ++ ;}cout << cnt; }

试题 H: 完全平方数

#include <iostream> #include <cmath> using namespace std;bool check(int x) {int t = (int)sqrt(x);if (t * t == x)return true;return false; }int main() {int n;cin >> n;for (int i = 1; i <= n; ++ i) {if (check(i * n)) {cout << i << endl;return 0;}} }

试题 I: 负载均衡

#include <iostream> #include <queue> using namespace std; typedef pair<int, int> PII; const int N = 2e5 + 10;int power[N]; priority_queue<PII, vector<PII>, greater<PII>> que[N]; // 小顶堆数组int main() {int n, m;cin >> n >> m;for (int i = 1; i <= n; ++ i)cin >> power[i];while (m -- ) {int a, b, c, d;cin >> a >> b >> c >> d;while (que[b].size() && que[b].top().first <= a) {power[b] += que[b].top().second;que[b].pop();}if (power[b] < d) {cout << -1 << endl;} else {power[b] -= d;cout << power[b] << endl;que[b].push({a + c, d});}} }

试题 J: 国际象棋

  • 典型的 状压dp
  • 由于这里行数比列数少,因此我们枚举每一列的摆放状态
  • f[i][a][b][j]f[i][a][b][j]f[i][a][b][j]表示考虑前i列,第i-1列状态为a,第i列状态为b,且一共放了j个马(因为这道题与数量有关)的方案数
  • 确定正确的初始状态
#include <iostream> using namespace std; const int N = 110, M = (1 << 6), K = 21, MOD = 1e9 + 7;int f[N][M][M][K];int get_count(int x) { // 二进制下1的个数int res = 0;while (x) {res ++ ;x -= (x & -x);}return res; }int main() {int n, m, k;cin >> n >> m >> k;f[0][0][0][0] = 1; // 初始状态for (int i = 1; i <= m; ++ i) { // 枚举每一列for (int a = 0; a < (1 << n); ++ a) { // 第i-2列for (int b = 0; b < (1 << n); ++ b) { // 第i-1列if ((a & (b << 2)) || ((a << 2) & b)) continue; // 状态矛盾for (int c = 0; c < (1 << n); ++ c) { // 第i列if ((c & (b << 2)) || ((c << 2) & b)) continue; // 状态矛盾if ((c & (a << 1)) || ((c << 1) & a)) continue; // 状态矛盾int t = get_count(c); // 根据第i列个数来确定总个数的下限for (int j = t; j <= k; ++ j) { // 枚举总个数f[i][b][c][j] = (f[i][b][c][j] + f[i - 1][a][b][j - t]) % MOD;}}}}}int res = 0;for (int i = 0; i < (1 << n); ++ i) {for (int j = 0; j < (1 << n); ++ j) {res = (res + f[m][i][j][k]) % MOD;}}cout << res; }

总结

以上是生活随笔为你收集整理的第十二届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学B组的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。