C++ 基礎模板
如果你使用 cin / cout
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
// code
return 0;
}
如果你使用 scanf / printf
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
// code
return 0;
}
建議平常使用 cin / cout
需要特殊輸入輸出時再用 scanf / printf
雷區
overflow
由於已經 #define int long long
了
比較不會有 overflow 的問題
字串
// 這是錯的
string s = "ABC" + "DEF";
“ABC” 型別是 const char[4]
(“ABC\0”)
"ABC" + "DEF"
就相當於 const char* + const char*
肯定炸 (就算成功加出來也會 UB)
這時通常需要把其中一個轉成 std::string
有 3 種轉換方式
string s = "ABC"s + "DEF";
string s = (string)"ABC" + "DEF";
string s = string("ABC") + "DEF";
(字元+字串也同理)
浮點數
這是一個經典的例子
double x = 0.1, y = 0.2;
bool eq = (x+y == 0.3);
if(eq) cout << "0.2+0.1 == 0.3";
else cout << "0.2+0.1 != 0.3";
輸出是 0.2+0.1 != 0.3
浮點數在電腦是以二進制近似值儲存的
二進制也是會有無限循環小數,有誤差
所以 b
會是 false
// 解決的方法是使用「容差」比較
// 避免直接使用 ==
double x = 0.1, y = 0.2;
bool eq = fabs(0.3 - (x+y)) < 1e-9;
相差 就將倆浮點數視為相等
// 也可以封裝成函數
bool equal(double a, double b) {
return fabs(a - b) < 1e-9;
}
// 然後 equal(x+y, 0.3);
建議浮點數用 double
如果用 float
需要改 Epsilon = 1e-6
(float 精度較低)
一些技巧
除以2
要記算 ÷2 時使用右移
(例如找中點)
// 慢
int m = (l+r)/2;
// 快
int m = (l+r)>>1;
×÷ 2 的倍數都可以用左右移
取2餘數
// 慢
int r = x%2;
// 快
int r = x&1;
( x&1
只會保留二進制最後一位元就相當於 x%2
)
善用 `&`
優化代碼速度
多使用 &
,避免不必要的複製
for(int& num : nums){
// ...
}
如果只讀取,不修改元素
可以使用 const&
for(const int& num : nums){
// ...
}
簡化代碼
vector<int> nums(10);
for(int& i : nums) cin >> i;
/*
否則你的 code 可能長成這樣
for(int i=0; i<nums.size(); i++){
cin >> nums[i];
}
*/