由于有些题目记得不是很清楚了,目前网上也没有找到国赛的题目,所以暂时写了一些我个人的思路,过几天如果找到了题目的话再附上我的代码。
A 合法密码
暴力跑一遍就可以了,但是pdf有换行,复制的时候要小心处理一下,答案好像是400。
B 选数概率
三个分数中,第二个分数的分母 20910,非常大所以组合数 的结果一定是 20910 或是其倍数。这个时候就可以写一个程序去算组合数,最后算出来当 a + b + c = 205,
。接着再用三层嵌套循环
的枚举三个整数 a,b,c,再去判断符不符合题目条件即可。最后算出来的结果是 a = 55, b = 94, c = 56。
C 蚂蚁开会
(不太记得题目了)
D 立定跳远
这道题是一道很明显的二分答案的题目,首先去二分长度,再去判断这个长度是不是符合题目的要求。使用特长跳跃 2L 的长度可以转化为多一个检查点。
这道题目与洛谷上面的 P2678 [NOIP2015 提高组] 跳石头 的思路非常类似。
E 最小字符串
(也有点不太记得题目了)
F 数位翻转
我先暴力预处理出来了 a 的一个翻转序列 b,然后用再用 dp(动态规划)来做。可以设 表示前 i 个数,已经翻转了 j 个区间,第 i 个数翻转与否的序列和的最大值。初始化
为序列 a 的前缀和,状态转移方程为
,
,最后结果是
。dp部分的时间复杂度是
,但前面预处理时间复杂度可能就比较高了。
G 数星星
感觉不是很擅长就没有仔细看
H 套手镯
没有想到应该怎么做,比赛时只想到把圆转换成正方形来做。
I 跳石头
比赛时写了一个记忆化DFS的暴力解法,没有想到正解,时间复杂度应该能接近 ,估计骗了不少分
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。
这个时候接着写下一道题就好了,让它在后台接着运行,有可能后面会出现不一样的地方。