一点小笔记
祝大家 RP++
# 0x01 环境配置
# Dev C++
# 自动保存
- 「工具 -> 编辑器选项 - > 自动保存 -> 启动编辑器自动保存」打勾,文件名 选择「附加格式化时间戳」
# 编译选项
「工具 -> 编译选项 -> 代码生成 / 优化 -> 连接器 -> 产生调试信息」 选择 YES
快捷键:启动调试
F5
下一步F7
打开
-Wall
选择 C++ 编译器标准:ISO C++98
# Vim
:vsp ~/.vimrc
set ts=4
set sw=4
set smarttab
set number
set expandtab
color desert
syntax on
set cindent
set guifont=Consolas:h16
set backspace=2
inoremap ( ()<ESC>i
inoremap [ []<ESC>i
inoremap { {}<ESC>i
inoremap < <><ESC>i
vmap <C-C> "+y
vmap <C-V> "+p
imap <C-V> <ESC>"+pa
vmap <BACKSPACE> d
imap <C-Z> <ESC>ua
vmap <C-Z> uv
imap <C-S> <ESC>:w<CR>a
vmap <C-S> :w<CR>v
imap <C-A> <ESC>ggVG
vmap <C-A> ggVG
# 0x02 注意事项
由于 CSP 的评测是在 Linux 的环境下完成的,因此有一些注意事项需要注意:
- 尽量不要使用
gets()
语句读取一行,因为这些函数使用换行符来判断行结束,Windows 下换行是\r\n
,而 Linux 下换行是\n
,假设某题的数据是在 Windows 下生成的,那么这道题的换行符就是\r\n
,最终比赛时的代码是在 Linux 下编译的,读取的换行符是\n
,这样就会导致读入错误。
kkksc03 评论:其实不使用
gets()
的原因主要还是潜在的溢出风险。
评测环境为 Linux 64 位,因此请注意指针变量占用的空间是
8
字节,注意计算内存,避免 MLE。在使用
long long
时请记得使用%lld
而非 WIndows 下的%I64d
。忌使用
__
(双下划线)开头的函数。int
*int
乘法强转long long
!减少不必要的优化,以降低思维难度、减少代码量和出错为目标。
next
,x0
,x1
,y0
,y1
,index
别作变量名!注意
long long
级别的INF
要开0x3f3f3f3f3f3f3f3fll
。long long
状压左移写1ll
。尽可能到 Linux 测样例!
比赛结束前 10 分钟就放弃治疗吧,别希望能绝杀。再三检查有没有去掉调试语句、是否能通过编译,文件输入输出是否正确,文件名和建立文件夹是否正确。
觉得该用
long long
就用!注意检查函数是否写了返回值类型,尤其是
inline
后面!Windows 下不会报错,尽量到 Linux 下测一次!别踢电源线!
# 0x03 小技巧 and Notes
# C++ 代码模板
#include <cstdio> | |
inline int read(){ | |
int x=0, f=1; char ch=getchar(); | |
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();} | |
while(ch>='0'&&ch<='9'){x=x*10+ch-48; ch=getchar();} | |
return x*f; | |
} | |
int main(){ | |
freopen("test.in", "r", stdin); | |
freopen("test.out", "w", stdout); | |
fclose(stdin); | |
fclose(stdout); | |
return 0; | |
} |
# 安全数组大小
记得开全局数组!!
int a[5792][5792]; // 5792*5792*4/1024/1024≈128 MiB. | |
int a[33554432]; // (≈3*10^7) 33554432*4/1024/1024= 128 MiB. | |
int a[8192][8192]; // 8192*8192*4/1024/1024≈256 MiB. | |
int a[67108864]; // (≈6*10^7) 67108864*4/1024/1024= 256 MiB. | |
int a[11585][11585]; //11585*11585*4/1024/1024≈512 MiB. | |
int a[134217728]; // (≈10^8) 134217728*4/1024/1024= 512 MiB. |
# 对拍
为了防止挂分,建议对拍,即用暴力和要提交的程序进行互相检测。
建议不会写数据生成器的同学恶补一下。
这里提供一种用 C++ 写的 Windows 对拍脚本,可以参考一下。
其中 data.exe
是数据生成器, std.exe
是暴力, test.exe
是要测的程序。
test.out
是要测的程序的输出文件, test.ans
是暴力的输出文件。
#include <bits/stdc++.h> | |
#include <windows.h> | |
using namespace std; | |
int main(){ | |
for(int i = 1; ; i++) { | |
Sleep(50); | |
system("data.exe"); | |
system("std.exe"); | |
syetem("test.exe"); | |
printf("-----------Test Case %d----------\n",cas); | |
if(system("fc test.out test.ans")) system("pause"); | |
} | |
} |
# 奇妙的语法
# inline
竞赛中尽量别用。
记得加函数返回值!
inline void MyFunction() { | |
// ... | |
} |
# 运算符重载
struct MyStruct { | |
int val; | |
bool operator<(const MyStruct &u1) const { | |
return val < u1.val; | |
} | |
} |
# IO
# long long 读写
记得用 %lld
!
long long a; | |
scanf("%lld", &a); // 读写 long long 注意用 % lld | |
printf("%lld", a); |
# 整行读入
#include <iostream> | |
#include <string> | |
std::string a; | |
getline(cin, a); |
# STL
# #include<math>
double pow(double x, double y); //x^y |
请勿使用 cmath
库中的 abs
函数!
//DO NOT USE THEM!!! | |
int abs(int i); | |
double fabs(double x); |
C++ 有很多
bug你想不到的事!相信 OIers 经常盯着一个他认为没毛病的程序,找问题。一小时后,他把
#include<cmath>
abs(n);改成
int myabs(int n){ if(n>=0) return n; return -n;}
后就 AC 了
来源:给所有准备竞赛的同学 - Nothing But Something - 洛谷博客
如果你非得要用 STL 的 abs
,请用 cstdlib
库中的。
# #include<algorithm>
sort
函数的第二个参数为待排序区间最后一个元素的后一个元素地址。
#include <algorithm> | |
int a[] = {/* ... */}; | |
std::sort(a, a + n); // 升序排序 a [0...n-1] | |
std::sort(a + 1, a + n + 1); // 升序排序 a [1...n] | |
bool cmp(int &u1, int &u2) { return u1 > u2; } // 重写比较函数 | |
std::sort(a, a + 1, cmp); // 降序排序 a [0...n-1] |
# #include<vector>
当数组用
#include <vector> | |
std::vector<int> a; | |
a.push_back(1); | |
a.insert(a.begin() + 5, 1); // 插入 | |
a.reverse(a.begin(), a.end()); // 翻转 | |
a.size(); // 查询大小 | |
a.empty(); // 查询是否为空 | |
a.clear(); // 清空 | |
b.erase(b.begin(), b.begin() + 3); // 删除 | |
std::vector<int> b = a; // 复制,速度极快 | |
a.swap(b); // 交换 | |
for (vector<int>::iterator i = a.begin(); i != a.end(); i++) // 迭代器 | |
printf("%d ", *i); |
# #include<queue>
#include <queue> | |
// Queue | |
std::queue<int> q1; // 队列 | |
q1.push(1); // 压入 | |
q1.front(); // 查询队头元素 | |
q1.pop(); // 弹出 | |
q1.empty(); // 查询是否为空 | |
q1.size(); // 查询大小 | |
// Deque | |
std::deque<int> q2; // 双端队列 | |
q2.push_back(1); | |
q2.push_front(1); | |
q2.pop_back(1); | |
q2.pop_front(1); | |
q2.back(); | |
q2.front(); | |
// Priority Queue | |
std::priority_queue<int> q3; // 优先队列(自动排序的队列) | |
// 默认升序排列,如果需要降序排列可重写小于号操作符 < |
# #include<utility>
#include<utility> | |
std::pair<int, int> a = std::make_pair(1, 2); |
# 0x7F 神奇的网站
数列推导式查询 OEIS
洛谷 luogu
# 引用 or 有帮助的文章
- 以梦为马,不负韶华 ——CSP2019 考前提醒
- 致 CSP 萌新 / 不会使用 NOI LINUX 的人群
- Noi Linux 的使用
- NOI Linux 使用心得
- 【模板】Noi-Linux 下的一些配置
- C/C++ 字符串与数字相互转换
- C++ sort 排序函数用法
- C++ 中 vector 使用详细说明 (转)