本讲稿适合准备参加美国计算机奥林匹克竞赛USACO,加拿大计算机竞赛CCC的学生阅读。默认阅读者已经学过编程语言,最好是C++。
本讲稿覆盖USACO涉及的大部分算法/数据结构/技巧,分成基础,铜组(Bronze division),银组(Silver division),金组(Gold division),白金组(Platinum division)五部分。
学习算法不只是提高你的编程水平,而是培养你解决问题的能力,这种能力也有益于别的领域/学科。Thinking twice,coding once.在你开始敲代码前先仔细想清楚你的思路(算法)。
算法竞赛是在限定的时间内写代码来解决问题,然后把你的代码提交给评测系统,评测系统事先准备好若干组输入数据和相应的输出数据作为测试点test case,把输入数据喂给选手的程序,在限定的时间(通常2s)和内存(通常256M)范围内产生出结果,把输出结果与测试点比较,一致就得分,即“黑盒测试”。
算法竞赛和软件开发不一样,不要求可维护性,不需要注释/文档,只要编程快(算法易实现),运行快,结果正确,只要你自己可读就行(只在比赛时可读)。
USACO每个赛季举办4次比赛:12月,1月,2月,US open(3月)。一般是4小时(US open是5小时)完成3道题,总分是1000分,每题333分(如果有15个测试点,每个测试点22分),总得分达到一定分数线就晋级,
练习时选择适合自己水平的题目,所谓适合自己水平,就是需要费劲思考才有解决方案,或者只能得大部分分数,剩余的小部分测试点只能看题解。如果你一看题目就知道怎么解决,这是太简单了。如果你只能得0分或少数分,那对你来说太难了。一般铜组题目思考15-20分钟还一无所获,银组题目思考30-40分钟还没有思路,那就可以看题解了;看别人的题解时先看一点点前面的提示,如果这时自己恍然大悟,就不要继续往下看了,而应该试着自己完成剩余部分。
一、基础知识
1.1尽量使用C++语言
C++是使用最广泛的参赛语言/题解语言。参赛所用C++只是C++语言的一个小子集,只是C语言加上标准模板库STL。
虽然在USACO,Python、Java时间限制是C++的两倍(4s),但还是C++程序运行更快,更易于满足时间限制。白金组使用Python有些测试点可能会超时。
在2020年12月之前,USACO采用文件输入输出,如下:
#include <cstdio>
using namespace std;
int main(){
freopen("problem-name.in","r",stdin);
freopen("prob