【洛谷】P8741 [蓝桥杯 2021 省 B] 填空问题 的题解

【洛谷】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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值