第十五届蓝桥杯 国赛 C/C++ 大学B组

由于有些题目记得不是很清楚了,目前网上也没有找到国赛的题目,所以暂时写了一些我个人的思路,过几天如果找到了题目的话再附上我的代码。

A 合法密码

暴力跑一遍就可以了,但是pdf有换行,复制的时候要小心处理一下,答案好像是400。

B 选数概率

三个分数中,第二个分数的分母 20910,非常大所以组合数 \binom{a + b + c}{2} (C_{a + b + c}^{2}) 的结果一定是 20910 或是其倍数。这个时候就可以写一个程序去算组合数,最后算出来当 a + b + c = 205,205 \times 204 = 41820 = 20910 \times 2。接着再用三层嵌套循环 O(n^{3}) 的枚举三个整数 a,b,c,再去判断符不符合题目条件即可。最后算出来的结果是 a = 55, b = 94, c = 56。

C 蚂蚁开会

(不太记得题目了)

D 立定跳远

这道题是一道很明显的二分答案的题目,首先去二分长度,再去判断这个长度是不是符合题目的要求。使用特长跳跃 2L 的长度可以转化为多一个检查点。

这道题目与洛谷上面的 P2678 [NOIP2015 提高组] 跳石头 的思路非常类似。

E 最小字符串

(也有点不太记得题目了)

F 数位翻转

我先暴力预处理出来了 a 的一个翻转序列 b,然后用再用 dp(动态规划)来做。可以设 f_{i, j, 0/1} 表示前 i 个数,已经翻转了 j 个区间,第 i 个数翻转与否的序列和的最大值。初始化 f_{i, 0, 0} 为序列 a 的前缀和,状态转移方程为 f_{i, j, 0} = max(f_{i - 1, j, 0}, f_{i - 1, j, 1}) + a[i]f_{i, j, 1} = max(f_{i - 1, j - 1, 0}, f_{i - 1, j - 1, 1}) + b[i],最后结果是 max_{j = 0}^{n} f_{n, j, 0/1}。dp部分的时间复杂度是 O(n^{2}),但前面预处理时间复杂度可能就比较高了。

G 数星星

感觉不是很擅长就没有仔细看

H 套手镯

没有想到应该怎么做,比赛时只想到把圆转换成正方形来做。

I 跳石头

比赛时写了一个记忆化DFS的暴力解法,没有想到正解,时间复杂度应该能接近 O(n^{2}),估计骗了不少分

J 最长回文前后缀

比赛时眨眼一看感觉好像很难就没有往下做。赛后想了一下,感觉好像可以用双指针做,两个指针分别指向字符串首尾,如果对应位置上的字符一样就两个往中间靠,但是还没有想到字符不一样的时候应该怎么处理。

快读模板

inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
}

        如果题目中有的变量需要用 long long 的话,可以直接在宏里面把 int 扩展到 long long,这样比较方便(如下图)。

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

#define int long long

inline int read() {
	int x = 0, f = 1; char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
}

// 代码

signed main() {
    // 代码
    return 0;
}

对拍代码

        整个对拍需要以下文件。bf.cpp文件里是暴力代码,std.cpp文件里是用了算法的代码,data.cpp用来生成输入样例,pai.cpp用来比较bf.cpp和stdcpp.out的结果是否相同。

        注意:每次更改bf.cpp,std.cpp或data.cpp之后都需要重新编译之后再运行pai.cpp进行对拍。

        接下来以输出 a + b 的程序来说明。

bf.cpp

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

int main() {
	int a, b, oup = 0;
	cin >> a >> b;
	for (int i = 1; i <= a; i++) oup++;
	for (int i = 1; i <= b; i++) oup++;
	cout << oup;
	return 0;
}

std.cpp 

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

int main() {
	int a, b;
	cin >> a >> b;
	if (a > 0) cout << a << endl;
	cout << a + b << endl;
	return 0;
}

data.cpp

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

int main() {
	srand(time(0));
	int a = rand(), b = rand(); // 随机生成两个数字
	cout << a << ' ' << b << endl; // 按照格式输出
	return 0;
}

pai.cpp

可以不用自己创建txt文件,编译运行一次pai.cpp之后会自动生成相应txt文件

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

int main() {
	int t = 1;
	while (1) {
		printf("test%d: ", t++);
		system("data.exe > in.txt"); // 用 data.exe 生成输入样例,并存入 in.txt 文件中
		system("std.exe < in.txt > stdout.txt");
        // 将 in.txt 文件中的输入样例用来测试 std.cpp 中的代码,并将结果输出到 stdout.txt 文件中
		system("bf.exe < in.txt > bfout.txt");
        // 将 in.txt 文件中的输入样例用来测试 bf.cpp 中的代码,并将结果输出到 bf.out 文件中

        // 比较 stdout.txt 和 bfout.txt 文件是否一样,一样返回 false,不一样返回 true
		if (system("fc stdout.txt bfout.txt")) {
			cout << "WA\n";
			return 0;
		}
		cout << "AC\n";
	}
	cout << "AC\n";
}

        下图是pai.cpp运行后的输出结果,会显示WA和输出不一样的地方。 

        如果输出样例一样的话,会一直显示AC。 

这个时候接着写下一道题就好了,让它在后台接着运行,有可能后面会出现不一样的地方。

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值