c++实用&鬼晦小技巧合集
\(update: 2025/10/20\)
全局变量定义
别用y1
y1是 < cmath > 中一个函数名,因此请避免使用或者定义为局部变量
随机数
\(rand()\)
没有设置的话,\(rand()\)默认是41(来自一位不知名的网友)
\(mt19937\)
更好的随机数
以下为用法
mt19937 rnd(time(0));
cout<<rnd();
其周期长度为\(2^{19937}-1\)
生成的数据范围为 \([0, 2^{32}-1(4294967295) ]\) (32位无符号整形) 显然炸int
代码中使用时间戳作为种子
快速读入
关闭同步流
ios::sync_with_stdio(0);
cout.tie(0);cin.tie(0);
快读
inline int read(){
int x=0,f=1;char ch=getchar();
while (ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
while (ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
必要时可将getchar()
换为getchar_unlocked()
,但请别轻易使用(会有些意外情况)
小数点相关
\(sqrt(x)\)
当\(x\ge 10^{18}\)时,他会炸
见p9118
cin/cout补充
保留小数
setprecision()
有四舍五入
//in
double x=0.3535;
cout<<setprecision(3)<<x;
//out
0.354
fixed
强制保留
//in
double x=0.3595;
cout<<fixed<<setprecision(3)<<x;
//out
0.360
设置输出长度
setw()
\(setw(n)\)
当后面紧跟着的输出字段长度小于\(n\)的时候,在该字段前面用空格(可以定义设置)补齐,当输出字段长度大于\(n\)时,全部整体输出。
//May all the beauty be blessed.
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
ios::sync_with_stdio(0);
cout.tie(0);cin.tie(0);
cout<<setw(10)<<setiosflags(ios::left)<<"abc"<<'\n'; // 设置宽度为10,左对齐
cout<<setw(10)<<setiosflags(ios::right)<<"the end"<<'\n';// 设置宽度为10,右对齐,
}
输出
abc
the end
setfill()
强制保留
cout<<"0."<<setw(10)<<setfill('0')<<123456789<<'\n';// 设置宽度为10,用'0来补足10个位置
输出
0.0123456789//除去前面的0.长度为10
vector函数
.find()
例
vector<int> a;
a.push_back(1);
a.push_back(3);
a.push_back(2);
a.push_back(0);
int x1=find(a.begin(),a.end(),1)-a.begin();
int x2=find(a.begin(),a.end(),4)-a.begin();
cout<<x1<<'\n'<<x2;
输出
0
4
.pop_back()
删除最后一个元素
多和排序一起使用
sort排序
这个可以实现由大到小排
sort(a.begin(),a.end(),greater<>());
关于运算级的有趣写法
你只需记住小括号高于一切就行
*=,/=相关
\(Q\):不想打sum=sum*a/b
怎么办?
\(A\):打(sum*=a)/=b
;
三目
\(Q\):输出时不想打这么多怎么办?
if(f) cout<<fpow(a,(b%k)+k)%m;
else cout<<fpow(a,b)%m;
\(A\):打这个
cout<<(f?fpow(a,(b%k)+k)%m:fpow(a,b)%m);
关于return
其实你除了return 0
以外,还可以写其他的
可爱型:return (0^_^0)
(前提:#define _ 0
);
可爱型2:return (0-0)
作死型:return 0.9
(您对c++的向下取整非常有自信)
犯懒型: (皇帝的新return别问为什么什么也没有)
压行与return 1
你是不是遇到过以下情况
if(...){
cout<<1;
return 0;
}
而迫于CE的原因不能将他们写成以下形式
if(...) cout<<1,return 0;
没关系,你可以这么写
if(...) return cout<<1,0;
是不是好看多了
压行与return 2
有时候你会在函数中遇到
void dfs(...){
if(...){
cout<<ans;
ans++;
return;
}
...
}
显然很长 且不好看
我们使用逗号表达式
void dfs(...){
if(...) return cout<<ans++,void();
...
}
是不是立即简洁明了了?
全排列
next_permutation()
用法类比数组
//May all the beauty be blessed.
#include<bits/stdc++.h>
//#define int long long
using namespace std;
int a[10];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
a[4]=5;
next_permutation(a,a+5);
for(int i=0;i<=4;i++) cout<<a[i]<<" ";
}
\(cout\)
1 2 3 5 4
关于换行
正常版
for(int i=1;i<=n;i++)
{
if(a[i]==1)
{
b[i]=a[i];
a[i]++;
}
}
//请不要在意这串代码在实现什么,因为我也不知道...
省事版(真正的正常版)
for(int i=1;i<=n;i++){
if(a[i]==1){
b[i]=a[i];
a[i]++;
}
}
某位王姓(学姐)学长的亲传码风
不省事版
for(int i=1;i<=n;i++)
{ if(a[i]==1)
{ b[i]=a[i];
a[i]++;
}
}
压行版(简洁高效超好用版)
某位王姓(学姐)学长的真正码风
for(int i=1;i<=n;i++) if(a[i]==1) b[i]=a[i]++;
鬼晦版(它还是太包容你了)
for(int i=1;i<=n;i++){
if(a[i]==1){
b[i]=a[i];
a[i]++;}
}
听说您就是下一届IOCCC的获奖者
结构体
重载小于号
struct aa{
int id,bg,t;
operator<(const aa a) const{
return t>a.t;//从大到小
}
};
生成函数
struct aa{
int id,bg,t;
aa(int id=0,int bg=0,int t=0):
id(id),bg(bg),t(t){};
};
用法:
aa a=aa();//id=0,bg=0,t=0
aa b=aa(1);// id=1 bg=0,t=0
矩阵相关
在写矩阵的时候有没有对 res.c[i][j]
感到麻烦?
现在可以直接写成 res[i][j]
了
转载自我也忘了的地方
struct matrix{ ll a[M][M];
ll* operator [](int x){ return a[x]; }
matrix operator *(matrix& b){
static matrix c;
for(int i=1;i<=3;++i)
for(int j=1;j<=3;++j)
c[i][j]=0;
for(int i=1;i<=3;++i)
for(int j=1;j<=3;++j)
for(int k=1;k<=3;++k)
c[i][j]+=a[i][k]*b[k][j],c[i][j]%=mod;
return c;
}
inline void print(){
for(int i=1;i<=n;++i,putchar('\n'))
for(int j=1;j<=n;++j,putchar(' '))
putchar('0'+a[i][j]);
}
}res;