一点小笔记

祝大家 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 的环境下完成的,因此有一些注意事项需要注意:

  1. 尽量不要使用 gets() 语句读取一行,因为这些函数使用换行符来判断行结束,Windows 下换行是 \r\n ,而 Linux 下换行是 \n ,假设某题的数据是在 Windows 下生成的,那么这道题的换行符就是 \r\n ,最终比赛时的代码是在 Linux 下编译的,读取的换行符是 \n ,这样就会导致读入错误。

kkksc03 评论:其实不使用 gets() 的原因主要还是潜在的溢出风险。

  1. 评测环境为 Linux 64 位,因此请注意指针变量占用的空间是 8 字节,注意计算内存,避免 MLE。

  2. 在使用 long long 时请记得使用 %lld 而非 WIndows 下的 %I64d

  3. 忌使用 __ (双下划线)开头的函数。

  4. int * int 乘法强转 long long

  5. 减少不必要的优化,以降低思维难度、减少代码量和出错为目标。

  6. next , x0 , x1 , y0 , y1 , index 别作变量名!

  7. 注意 long long 级别的 INF 要开 0x3f3f3f3f3f3f3f3fll

  8. long long 状压左移写 1ll

  9. 尽可能到 Linux 测样例!

  10. 比赛结束前 10 分钟就放弃治疗吧,别希望能绝杀。再三检查有没有去掉调试语句、是否能通过编译,文件输入输出是否正确,文件名和建立文件夹是否正确。

  11. 觉得该用 long long 就用!

  12. 注意检查函数是否写了返回值类型,尤其是 inline 后面!Windows 下不会报错,尽量到 Linux 下测一次!

  13. 别踢电源线!

# 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 有帮助的文章

  1. 以梦为马,不负韶华 ——CSP2019 考前提醒
  2. 致 CSP 萌新 / 不会使用 NOI LINUX 的人群
  3. Noi Linux 的使用
  4. NOI Linux 使用心得
  5. 【模板】Noi-Linux 下的一些配置
  6. C/C++ 字符串与数字相互转换
  7. C++ sort 排序函数用法
  8. C++ 中 vector 使用详细说明 (转)
Edited on

Give me a cup of [coffee]~( ̄▽ ̄)~*

Fidel WeChat Pay

WeChat Pay

Fidel Alipay

Alipay

Fidel afdian

afdian