0
点赞
收藏
分享

微信扫一扫

第十二届省赛蓝桥杯(B组)

J简文 2022-03-22 阅读 129
c++蓝桥杯

试题 A: 空间 本题总分:5 分

问题描述】 小蓝准备用 256MB 的内存空间开一个数组,数组的每个元素都是 32 位 二进制整数,如果不考虑程序占用的空间和维护内存需要的辅助空间,请问 256MB 的空间可以存储多少个 32 位二进制整数?

【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include <bits/stdc++.h>

using namespace std;

int main()
{
// MB KB B b
int res = 256 * 1024 * 1024 / 4;

cout << res << endl;

// 67108864


return 0;
}

试题 B: 卡片 本题总分:5 分

【问题描述】 小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。 小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个, 就保存起来,卡片就不能用来拼其它数了。 小蓝想知道自己能从 1 拼到多少。 例如,当小蓝有 30 张卡片,其中 0 到 9 各 3 张,则小蓝可以拼出 1 到 10, 但是拼 11 时卡片 1 已经只有一张了,不够拼出 11。 现在小蓝手里有 0 到 9 的卡片各 2021 张,共 20210 张,请问小蓝可以从 1 拼到多少? 提示:建议使用计算机编程解决问题。

【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include <bits/stdc++.h>

using namespace std;

const int N = 10;

int p[N];

int main()
{

for (int i = 0; i < N; i ++ ) p[i] = 2021;

for (int i = 1; i < 1e7; i ++ )
{
int x = i;
while (x)
{
int t = x % 10;
p[t] -- ;
if (p[t] < 0)
{
cout << i - 1<< endl;
return 0;
}
x /= 10;
}
}

// 3181

cout << "No" << endl;

return 0;
}

试题 C: 直线 本题总分:10 分

【问题描述】 在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。 给定平面上 2 × 3 个整点 {(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z},即横坐标 是 0 到 1 (包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数 的点。这些点一共确定了 11 条不同的直线。 给定平面上 20 × 21 个整点 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z},即横 坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20) 之 间的整数的点。请问这些点一共确定了多少条不同的直线。

【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include <bits/stdc++.h>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1000000, INF = 1e9;

PII p[N];
int len, l;

struct line
{
double k;
double d;
int x;
int y;
}dist[N];

bool check(double k, double d, int x, int y)
{
for(int i = 0; i < l; i ++ )
{
if ( fabs(k - dist[i].k) <= 1e-9 && fabs(d - dist[i].d) <= 1e-9 &&
x == dist[i].x = dist[i].y )
return false;
}
return true;
}

int main()
{
int n, m;
n = 20, m = 21;

for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
p[len ++ ] = {i, j};

for (int i = 0; i < len - 1; i ++ )
{
for (int j = i; j < len; j ++ )
{
if (i == j) continue;

double x1 = p[i].x, y1 = p[i].y;
double x2 = p[j].x, y2 = p[j].y;
if (x2 == x1)
{
if(check(INF, INF, x1, INF))
{
dist[l].k = INF;
dist[l].d = INF;
dist[l].x = x1;
dist[l].y = INF;
l ++ ;
}
}
else if (y2 == y1)
{
if(check(INF, INF, INF, y1))
{
dist[l].k = INF;
dist[l].d = INF;
dist[l].x = INF;
dist[l].y = y1;
l ++ ;
}
}
else
{
double k = (y1 - y2) / (x1 - x2);
double d = y1 - k * x1;
if (check(k, d, INF, INF))
{
dist[l].k = k;
dist[l].d = d;
dist[l].x = INF;
dist[l].y = INF;
l ++ ;
}
}
}
}


cout << l << endl;
// 40257


return 0;
}

(浮点数比较注意精度)

试题 D: 货物摆放 本题总分:10 分

【问题描述】 小蓝有一个超大的仓库,可以摆放很多货物。 现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝 规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、 宽、高。 小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上 分别堆 L、W、H 的货物,满足 n = L × W × H。 给定 n,请问有多少种堆放货物的方案满足要求。 例如,当 n = 4 时,有以下 6 种方案:1×1×4、1×2×2、1×4×1、2×1×2、 2 × 2 × 1、4 × 1 × 1。 请问,当 n = 2021041820210418 (注意有 16 位数字)时,总共有多少种 方案? 提示:建议使用计算机编程解决问题。

【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

第一眼,暴力(超时)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

int main()
{
register LL res = 0;
register LL n = 2021041820210418;

cout << n << endl;

cout << n * n << endl;

for (LL i = 1; i <= n; i ++ )
for (LL j = 1; j <= n / i; j ++ )
if (n / (i * j * 1.0) == n / (i * j))
{
cout << res << endl;
res ++ ;
}
cout << res << endl;

return 0;
}

没关系,有问题上百度,求约数暴力。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 1000010;

LL gcd[N];

int main()
{
LL n = 2021041820210418;
int len = 0;
LL res = 0;

for (LL i = 1; i <= n / i; i ++ )
if (n % i == 0)
{
gcd[len ++ ] = i;
if (i * i != n)
gcd[len ++ ] = n / i;
}

for (int i = 0; i < len; i ++ )
for (int j = 0; j < len; j ++ )
if (n % (gcd[i] * gcd[j]) == 0)
res ++ ;


cout << res << endl;

return 0;
}

试题 E: 路径 本题总分:15 分

【问题描述】 小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图 中的最短路径。 小蓝的图由 2021 个结点组成,依次编号 1 至 2021。 对于两个不同的结点 a, b,如果 a 和 b 的差的绝对值大于 21,则两个结点 之间没有边相连;如果 a 和 b 的差的绝对值小于等于 21,则两个点之间有一条 长度为 a 和 b 的最小公倍数的无向边相连。 例如:结点 1 和结点 23 之间没有边相连;结点 3 和结点 24 之间有一条无 向边,长度为 24;结点 15 和结点 25 之间有一条无向边,长度为 75。 请计算,结点 1 和结点 2021 之间的最短路径长度是多少。 提示:建议使用计算机编程解决问题。

【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

#include <bits/stdc++.h>

using namespace std;

const int N = 2050, M = 2021;

int vist[N][N];

int gcd(int x, int y)
{
return y == 0 ? x : gcd(y, x % y);
}

void floyd(int vist[][N])
{
for (int k = 1; k <= M; k ++ )
for (int i = 1; i <= M; i ++ )
for (int j = 1; j <= M; j ++ )
if (vist[i][j] > vist[i][k] + vist[k][j])
vist[i][j] = vist[i][k] + vist[k][j];
}

int main()
{

memset(vist, 0x3f, sizeof vist);


for (int i = 1; i <= M; i ++ )
for (int j = 1; j <= M; j ++ )
{
if (i == j) vist[i][j] = 0;
else
{
if (abs(i - j) <= 21)
{
int len = (i * j) / gcd(i, j);
vist[i][j] = len;
vist[j][i] = len;
}
}
}

floyd(vist);

cout << vist[1][2021] << endl;

// 10266837

return 0;
}
举报

相关推荐

0 条评论