C/C++ 基础知识篇:点击打开链接
ACM IO 模板(控制台版):
#include<bits/stdc++.h> #include<cmath> #define mem(a,b) memset(a,b,sizeof a) #define ssclr(ss) ss.clear(), ss.str("") #define INF 0x3f3f3f3f #define MOD 1000000007 using namespace std; typedef long long ll; int main() { // int T; scanf("%d",&T); // int n; // while(T-- && ~scanf("%d",&n)) // { int n; while(~scanf("%d",&n)) { } return 0; }
ACM IO 模板(文件版)
#include<bits/stdc++.h> #include<cmath> #define mem(a,b) memset(a,b,sizeof a) #define ssclr(ss) ss.clear(), ss.str("") #define INF 0x3f3f3f3f #define MOD 1000000007 using namespace std; typedef long long ll; int main() { freopen("data.txt", "r", stdin); // 必须创建,文件保存在源文件同个目录下 freopen("data.txt", "w", stdout); // 无需创建自动生成 /* 中间按原样写代码,什么都不用修改 */ int n; while(~scanf("%d",&n)) { printf("%d\n",n); } fclose(stdin); fclose(stdout); return 0; }
URDL(二维 / 三维):
// URDL:二维 const int di[4]={-1,0,1,0}; const int dj[4]={0,1,0,-1}; // UDRL i from 0 to 3(二维) int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 }; // URDL:三维 const int X[6]={1,0,0,-1,0,0}; const int Y[6]={0,1,0,0,-1,0}; const int Z[6]={0,0,1,0,0,-1};
斐波那契数列与三角形的关系。点击打开链接
卡特兰数点击打开链接
有时候,全局变量对 DFS 是禁忌,特别是每次回溯时需要变回起初的值的变量,如果用全局替代局部变量的话,一旦改变就回不去起初的“还原点”了。
DFS 时,有时候可以用比较好看出的值代入看看是否正常,大概感觉对即可,不求甚解。
正整数分解成(可相同或不相同的数)使得乘积最大。点击打开链接
快速求解二进制 1 的个数
//
ll numOf1(ll n) { ll cnt = 0; while(n){ cnt++; // 只要 n 不为 0,则其至少有一个 1 n = n & (n - 1); } return cnt; }
算法竞赛中,关闭iostream对象和cstdio流同步以提高输入输出的效率。
1、即调用ios::sync_with_studio(false); 特别注意:关闭后C++ IO与C IO不能混用,cin不能与scanf,sscanf, getchar, fgets等混用,cout不能与printf,puts等混用,否则IO会混乱。
2、在默认的情况下cin绑定的是cout,每次执行 << 操作符的时候都要调用flush,这样会增加IO负担。可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率。即调用std::cin.tie(0)。
/
std::ios::sync_with_stdio(false); std::cin.tie(0);
多重循环直接跳出技巧:
for(int i=0,f=1;i<n&&f;i++) for(int j=0;j<n&&f;j++) if(1) f=0;
C++不检查数组越界情况?
答:看编译器是否对这方面进行调改过,如果越界也不报运行错误的话,就报WA,但有些OJ编译器可以检查出的话就报RE。
“printf、scanf” 和 其他表达式可以用 “,” 写成一句,但是 “break、continue、return” 必须独自一句。
一道题目多种解决方法时,比较下时间复杂度。比如:点击打开链接(m都一样的情况:以 n 为主体AC,但以 k 为主体TLE)
当人脑debug时,或者一些数据不确定时,选择数据量尽可能少的例子来确定代码,因为代码是通用的。
输出的时候,尽可能用“&”引用(参数复制速度比较慢,所以上引用)。
PAT 中,gets 函数用不了。
对于一些分类的题目,可以用优先级标记来区分,这样只要一次sort即可,否则要多次sort,这样时间消耗方面还是有差别的。
有时候建树时,没出现的结点就是 root:
for(int i=0;i<n;i++) if(!vis[i]){rt=i; break;} /* 9 7 8 - - - - - - 0 1 2 3 4 5 - - - - */
保留小数部分技巧:如果判断保留 n 位小数,则判断第 n+1 位数字与 “5” 做比较再进行处理。
完全二叉树判定:第一次出现空儿子后,接下来如果有出现真儿子,则 NO,否则 YES。
有些题目不要全都算出来,需要用到哪个就算哪个,这样可以节省没必要算的时间。
写在一个括号里的变量需要注意:如果 bfs 函数里有对 rs 操作则最终效果是不理想的,因为这里的 rs 在没运行 bfs 之前就已经旧值赋值上去了,即使中途改变了 rs,也是 rs 被更新,但是这里的 %d 输出仍然是之前未改变的 rs 值:
/
printf(bfs()?"YES %d\n":"NO %d\n",rs);
小技巧:
for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(i) join(a[i-1],a[i]); }
- 自定义稳定排序:添加个唯一值标号(从小到大比较)。
- char* 效率高于 string。
- 小技巧:写入名字 并 计算名字前有多少空格。
int calSp(char name[]) { char c; int cnt=0,k=0; while((c=getchar())==' ') cnt++; do { name[k++]=c; }while((c=getchar())!='\n'); name[k]='\0'; return cnt; }