【蓝桥杯】第十五届C++B组省赛

发布于:2025-04-03 ⋅ 阅读:(23) ⋅ 点赞:(0)
头像
⭐️个人主页:@小羊
⭐️所属专栏:蓝桥杯
很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~

动图描述


试题A:握手问题

在这里插入图片描述

我和其他49个人握手,第二个人和其他48个人握手,第三个和其他47个人握手…到倒数第7个人时不再握手。结果是:1024。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int tol = 0;
    for (int i = 49; i >= 7; i--)
        tol += i;
    cout << tol << endl;
    return 0;
}

试题B:小球反弹

在这里插入图片描述
在这里插入图片描述

结果是:1100325199.77

#include <bits/stdc++.h>
using namespace std;

int main()
{
	long long t = 1, x = 343720, y = 233333, dx = 15, dy = 17;
	while (true)
	{
		if ((t * dx) % x == 0 && (t * dy) % y == 0) break;
		t++;
	}
	printf("%.2f\n", 2 * sqrt(dx * dx + dy * dy) * t);
	return 0;
}

试题C:好数

在这里插入图片描述

用一个值标记奇数位还是偶数位。

#include <bits/stdc++.h>
using namespace std;

bool check(int n)
{
    int i = 1; // 标记奇数位还是偶数位
    while (n)
    {
        if (i % 2 != n % 2) return false;
        i++;
        n /=10;
    }
    return true;
}

int main()
{
    int n, ret = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        if (check(i)) ret++;
    }
    cout << ret << endl;
    return 0;
}

试题D:R格式

在这里插入图片描述

// 样例输入
2 3.14
// 样例输出
13

算是高精度乘法,首先将字符串逆序方便计算,记录下小数点的位置,后面四舍五入要用,做乘法的时候需要处理好进位,最后四舍五入的时候也要处理进位。
当我们记录下小数点的位置把小数点去掉后,相应数的位置就发生的改变,需要注意映射关系。

#include <bits/stdc++.h>
using namespace std;

void mul(vector<int>& D)
{
   int t = 0;//记录进位
   for (int i = 0; i < D.size(); i++)
   {
       t += D[i] * 2;
       D[i] = t % 10;
       t /= 10;
   }
   if (t) D.push_back(1);
}
void add(vector<int>& D, int pos)
{
    int t = 1;
    for (int i = pos; i < D.size(); i++)
    {
        t += D[i];
        D[i] = t % 10;
        t /= 10;
    }
    if (t) D.push_back(1);
}
int main()
{
    int n;
    string d;
    cin >> n >> d;
    reverse(d.begin(), d.end());
    int pos = d.find('.');// 记录下小数点的位置
    vector<int> D;
    for (char ch : d)
        if (ch != '.')
            D.push_back(ch - '0');
    while (n--) mul(D);
    if (D[pos - 1] >= 5) add(D, pos);
    for (int i = D.size() - 1; i >= pos; i--)
        cout << D[i];
    return 0;
}

试题E:宝石组合

在这里插入图片描述

// 样例输入
5
1 2 3 4 9
// 样例输出
1 2 3


试题F:数字接龙

在这里插入图片描述
在这里插入图片描述

// 样例输入
3 3
0 2 0
1 1 1
2 0 2
// 样例输出
41255214

很明显的dfs,初始化向量坐标的时候按照题目要求初始化,方便记录路径。
用四维数组判断是否交叉,两个方向都要判断。

#include <bits/stdc++.h>
using namespace std;

int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int N = 20;
int a[N][N];
bool used[N][N], f[N][N][N][N];
int n, m;
string ret;

bool dfs(int i, int j)
{
	if (i == n - 1 && j == n - 1) return ret.size() == n * n - 1;
	used[i][j] = true;
	for (int k = 0; k < 8; k++)
	{
		int x = i + dx[k],  y = j + dy[k];
		if (x < 0 || x >= n || y < 0 || y >= n) continue;
		if ((a[i][j] + 1) % m != a[x][y] || used[x][y]) continue;
		if (f[i][y][x][j] || f[x][j][i][y]) continue;
		
		f[i][j][x][y] = true;
		ret += k + '0'; 
		if (dfs(x, y)) return true;
		ret.pop_back();
		f[i][j][x][y] = false;
	}
	used[i][j] = false;
	return false;
}

int main()
{
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)	
			cin >> a[i][j];
	if (dfs(0, 0)) cout << ret << endl;
	else cout << -1 << endl;
	return 0;
}

试题G:爬山

在这里插入图片描述

// 样例输入
4 1 1
4 5 6 49
// 样例输出
18


试题H:拔河

在这里插入图片描述

// 样例输入
5
10 9 8 12 14
// 样例输出
1

用前缀和数组统计出所有子区间的和,然后排升序,统计出相邻子区间和的最小值。

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const int N = 1e3 + 10;
ll a[N], pre[N];
ll n, ret = LLONG_MAX;
vector<ll> v;

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		pre[i] = pre[i - 1] + a[i]; // 计算前缀和数组 
	}
	for (int r = 2; r <= n; r++)
		for (int l = 1; l < r; l++)
			v.push_back(pre[r] - pre[l]);
	sort(v.begin(), v.end()); // 对所有子区间和排序 
	for (int i = 1; i < v.size(); i++)
		ret = min(ret, abs(v[i] - v[i - 1])); // 找到相邻两个子区间和最小值 
	cout << ret << endl; 
	return 0;
}

本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

头像