【洛谷】P8741 [蓝桥杯 2021 省 B] 填空问题 的题解
传送门
A
这题没什么好说的,直接暴力。
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << 256 * 1024 * 1024 / 4;
return 0;
}
得到答案 67108864 67108864 67108864。
B
直接暴力求解,主要最后的结果 − 1 -1 −1,因为刚好到该数的时候超过限制值,所以只能拼到该数的前一个数。
#include <bits/stdc++.h>
using namespace std;
int a[25];
int main() {
for(int i = 0; i <= 9; i ++) {
a[i] = 2021;
}
int ans = 0, f = 0;
for(int i = 1; ; i ++) {
int j = i;
while(j) {
if(a[j % 10])
a[j % 10] --;
else {
f = 1;
break;
}
j /= 10;
}
if(f) {
ans = i;
break;
}
}
cout << ans - 1;
return 0;
}
得到答案 3181 3181 3181。
C
这些方案中的每一个长宽高都将是 n n n 的因子,所以这题就转化为求 n n n 的因子,在求出的 n n n 的因子中寻找可能的方案数。
#include <bits/stdc++.h>
using namespace std;
long long int a[3035], n = 2021041820210418, ans = 0;
void fun() {
for(long long int i = 1; i * i <= n; i ++) {
if(n % i == 0) {
a[ans ++] = i;
if(i * i != n)
a[ans ++] = n / i;
}
}
}
int main() {
fun();
long long int sum = 0;
for(long long int i = 0; i < ans; i ++) {
for(long long int j = 0; j < ans; j ++) {
for(long long int k = 0; k < ans; k ++) {
if(a[i] * a[j] * a[k] == n) {
sum ++;
}
}
}
}
cout << sum;
return 0;
}
得到答案 40257 40257 40257。
D
确定一条直线的方式有很多种,但是我们知道,一个斜率和一个截距将会唯一确定一条直线,所以我们枚举所有的点,算出所有两点确定一条直线的斜率和截距,然后通过 map 去重,找到其中不一样的,横线和竖线很好算,这个单独考虑。
#include<bits/stdc++.h>
using namespace std;
map<pair<double, double>, int> a;
struct point {
double x;
double y;
} point[1005];
int main() {
int ans = 0;
for(int i = 0; i < 20; i ++) {
for(int j = 0; j < 21; j ++) {
point[ans].x = i;
point[ans].y = j;
ans ++;
}
}
int sum = 0;
for(int i = 0; i < ans; i ++) {
for(int j = 0; j < ans; j ++) {
if(point[i].x == point[j].x || point[i].y == point[j].y)
continue;
double k = (point[i].y - point[j].y) / (point[i].x - point[j].x);
double b = (point[i].x * point[j].y - point[j].x * point[i].y) / (point[i].x-point[j].x);
if(a[{k, b}] == 0) {
a[{k, b}] = 1;
sum ++;
}
}
}
cout << sum + 21 + 20;
return 0;
}
得到答案 2430 2430 2430。
E
思路:这道题直接就用 floyd 算法跑就行,反正填空题也不怕超时,三层循环等个几十秒就出来了。迪杰斯特拉写着太麻烦了。
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
#define INT 0x3f3f3f3f
ll Edge[2025][2025];
int gcd(int a, int b) {
if (b == 0)
return a;
return gcd(b, a % b);
}
int lcm(int a, int b) {
int c = a * b;
return c / gcd(a, b);
}
int main() {
memset(Edge, INT, sizeof(Edge));
for (int i = 1; i <= 2021; i ++) {
for (int j = 1; j <= 2021; j ++) {
if (i == j)Edge[i][j] = 0;
else {
if (abs(i - j) <= 21) {
Edge[i][j] = lcm(i, j);
}
}
}
}
for (int k = 1; k <= 2021; k ++) {
for (int i = 1; i <= 2021; i ++) {
for (int j = 1; j <= 2021; j ++) {
if (Edge[i][j] > Edge[i][k] + Edge[k][j]) {
Edge[i][j] = Edge[i][k] + Edge[k][j];
}
}
}
}
cout << Edge[1][2021];
return 0;
}
得到答案 10266837 10266837 10266837。
AC代码
#include<iostream>
using namespace std;
int main() {
string ans [] = {
"67108864",
"3181",
"40257",
"2430",
"10266837",
};
char T;
cin >> T;
cout << ans[T - 'A'] << endl;
return 0;
}
文章提供了五道不同难度的编程竞赛题目解法,涉及暴力求解、因子计算、直线确定和最短路径算法。题目包括计算内存大小、拼数字游戏、找立方体组合数、不重复直线数量和两数之最小公倍数路径问题。
8758

被折叠的 条评论
为什么被折叠?



