持续更新
头文件部分
头文件按照长度升序
开
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
一般会用
替代掉一些较长的单词或函数,需要注意的是一定要小心优先级!
用法:
+空格+
,表示用
替代掉
,比
好用很对
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
#define ri register int
不过推荐定义变量的时候用 ,这样更稳定,定义方法与 相反
typedef long long LL;
typedef unsigned long long ULL;
变量定义部分
一般喜欢把常用变量接在std后面,不同类型数组经常单开一行,当一道题用到多种算法时有时会把同种算法的数组放一起
数组空间一般开 ,比赛时会开
结构体风格,当成员比较小时,一般都是一行写完(压行),下一行再加上配套的函数或过程
如邻接表结构体:
int tot,l[N];
struct node{int next,to,w;}e[M<<1];
inline void add(int u,int v,int w){e[++tot]=(node){l[u],v,w};l[u]=tot;return;}
若成员较多或带有函数时,一般会按照主程序的码风打,如矢量结构体
struct node
{
double x,y,p;
friend node operator -(const node&a,const node&b){return (node){a.x-b.x,a.y-b.y,atan2(a.y-b.y,a.x-b.x)};}
friend double operator *(const node&a,const node&b){return a.x*b.y-a.y*b.x;};
}a[10005];
子函数和过程
一般会在函数或过程前加 ,过程会习惯 ,原因是因为有一次刷线段树时加了 快了近400
当参数比较少时,一般会在参数前加 优化常数,如并查集
inline int find(register int x){return x==f[x]?x:f[x]=find(f[x]);}
若函数过长——单行时超出Dev-C++显示范围,都不压行,按照正常程序的码风打
代码:
inline void spfa(re int S,re int *dis)
{
while(q.size()) q.pop();
q.push(S);vis[S]=true;dis[S]=0;
while(q.size())
{
int x=q.front();q.pop();vis[x]=true;
for(re int i=l[x];i;i=e[i].next)
{
int y=e[i].to,w=e[i].w;
if(dis[x]+w<dis[y])
{
dis[y]=dis[x]+w;
if(!vis[y]) vis[y]=true,q.push(y);
}
}
vis[x]=false;
}
return;
}
主程序风格
前加 而不用
从来不打 ,比赛除外
循环变量一般都加 ,喜欢用 替代
大括号一一对应,换一行打
后能用逗号连接就用,不能用加大括号,短时压行,不短的时候按子程序的码风打
能用位运算就用位运算
用
而不用
能用
绝不用
dfs
一般都是按层次搜索,这样无论是树形问题还是比较复杂的问题都可以用 打暴力,当每件物品只存在选或不选时,一般会用二进制状态压缩
inline void dfs(int 层次,……各种参数)
{
if(now<ans) return;//最优化剪枝,有时候不能用,要分析正确性
if(层次>n) {ans=min(ans,now);return;}
if(条件1) dfs(层次+1,条件1的分支);//注:有时候不一定有条件,根据实际需要打
if(条件2)
{
for(遍历可选择集合的点,或者直接遍历所有元素再判断合法)//一般前者会快点,例如邻接表
{
判断是否合法
需要标记则标记
dfs(层次+1,当前子节点)
若需要取消标记则取消
如果子节点与父节点存在转移关系则转移
}
}
}
bfs
能用 就用 ,比赛时更喜欢打 因为更稳,但 一般更好蹭分