標準樣板函式庫
Standard Template Library
裡面有很多容器、函式
很多好用的工具
演算法的基礎
請務必學會並弄熟
常用功能:
push_back
pop_back
clear
size
empty
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v;
//宣告一個陣列
vector<char>a(10);
//大小為10
vector<int>b={1,3,5};
//直接指定大小&賦值
vector<int>(12,0);
//大小為4且都放0
}vector<資料型態> 名稱;
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v;
v.emplace_back(1);
//加入元素 較快
v.push_back(2);
//加入元素 較慢
v.pop_back();
//移除尾端元素
}push_back(值);
emplace_back(值);
pop_back();
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v;
v.emplace_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
cout<<v[2];
}基本上陣列可以做到的
vector也都可以
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int>v;
v.emplace_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
cout<<v.front()<<v.back()<<v[2];
}front():第一項
back():最末項
基本上陣列可以做到的
vector也都可以
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> v;
cout<<"初始:size="<<v.size()<<" capacity="<<v.capacity()<<'\n';
for (int i = 1; i <= 10; i++) {
v.push_back(i);
cout<<"插入"<<i<<"->size="<<v.size()<<" capacity="<<v.capacity()<<'\n';
}
}size():取得vector的長度
capacity():陣列加上預留的格子
empty():判斷是否為空 回傳布林值
size():vector長度
capacity():預留的記憶體空間(通常用倍增)
vector是一排的盒子
iterater像指針 指向陣列的位置(不是值)
宣告方法:
vector<int>::iterator it;變數it 是指向vector<int>的迭代器型別
begin():vector第一格的位置
end():vector最後一格"再下一格"的位置
移動迭代器:
it++:移到下一格
it--:移到上一格
1.用for
跑過整個陣列
vector<int>v={1,2,3,4,5};
for(int i=0;i<5;i++){
cout<<v[i]<<' ';
}跟陣列一樣
2.用剛剛學過的迭代器
vector<int>v={1,2,3,4,5};
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<' ';//'*'用來取值
}這樣也太長了吧
在C++11後 提供auto可以自動判斷型別
vector<int>v={1,2,3,4,5};
for(auto it=v.begin();it!=v.end();it++){
cout<<*it<<' ';
}3.range-based for
vector<int>v={1,2,3,4,5};
for(int i:v){
cout<<i<<' ';
}複製每個元素到i裡面
但是改動i不會影響v裡面的東西
vector<int>v={1,2,3,4,5};
for(int i:v){
cout<<i<<' ';
i+=10;
}
cout<<'\n';
for(int x:v){
cout<<x<<' ';
}變數的別名
所以改動的時候也會改動原變數
在變數前面加上'&'
vector<int>v={1,2,3,4,5};
for(int &i:v){
cout<<i<<' ';
i+=10;//用了參照 v裡面的值也會改
}
cout<<'\n';
for(int x:v){
cout<<x<<' ';
}常用:
sort():由小到大排
reverse():反轉
swap():兩元素調換
fill():填滿陣列格子
resize():重新定義大小
vector<int>v={1,2,3,4,5};
sort(v.begin(),v.end());
reverse(v.begin(),v.end());
swap(v[1],v[3]);
fill(v.begin(),v.end(),0);
v.resize(10);未來的圖論會用到
也可以直接當成陣列使用
是個極為方便的工具
o076
#include<bits/stdc++.h>
using namespace std;
vector<int>v;
int main(){
int n;cin>>n;
for(int i=0;i<n;i++){
int a;cin>>a;
v.push_back(a);
}
int x=v[0],tmp=1,ans=1;
for(int i=1;i<n;i++){
if(v[i]<v[i-1])tmp++;
else tmp=1;
ans=max(ans,tmp);
}
cout<<ans<<'\n';
}
toj 575
#include<bits/stdc++.h>
#define maxn 1000005
using namespace std;
vector<int>g[maxn];
int main(){
int n,k;cin>>n>>k;
for(int i=0;i<k;i++){
int a,b;cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
for(int i=1;i<=n;i++){
sort(g[i].begin(),g[i].end());
for(auto x:g[i]){
cout<<x<<' ';
}
cout<<'\n';
}
}把兩組資料綁在一起
看成一種新的型態
pair<int,int>p宣告方式跟vector很像
pair<資料型態,資料型態>名稱;
first:第一項
second:第二項
#include<bits/stdc++.h>
using namespace std;
int main(){
pair<int,int>p;
p.first=3;//將第一項設成3
p.second=5;
cout<<p.first<<' '<<p.second<<'\n';
}宣告方式跟vector很像
pair<資料型態,資料型態>名稱;
不用加()
pair裡面可以裝整數
當然也可以裝任何資料型態
#include<bits/stdc++.h>
using namespace std;
int main(){
pair<int,int>p;
pair<int,pair<int,int>>p1;
pair<int,char>p2;
pair<vector<int>,pair<int,int>>p3;
}vector也不例外
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int>v;
vector<pair<int,int>>v1;
vector<vector<int>>v2;
}在傳入和輸出的時候有些要注意
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<pair<int,int>>v;
v.push_back(make_pair(3,5));
v.push_back({3,5});
v.emplace_back(3,5);
}vector要放pair要加make_pair(a,b)或{a,b}
emplace_back(a,b)直接放
pair不能直接輸出 要分開用first second取
在用sort()函式比較pair的大小時
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<pair<int,int>>v;
v.push_back(make_pair(3,5));
v.push_back({5,5});
v.emplace_back(5,7);
sort(v.begin(),v.end());
}會先比較first 再比較second
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
vector<pair<int,int>>v;
for(int i=0;i<n;i++){
int x,y;
cin>>x>>y;
v.push_back({x,y});
}
sort(v.begin(),v.end());
for(auto i:v)cout<<i.first<<' '<<i.second<<'\n';
}a130
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;cin>>t;
int cnt=1;
while(t--){
int mx=0;
vector<pair<string,int>>v;
for(int i=0;i<10;i++){
string c;
int a;
cin>>c>>a;
v.push_back({c,a});
mx=max(mx,a);
}
cout<<"Case #"<<cnt<<":\n";
for(int i=0;i<10;i++){
if(mx==v[i].second)cout<<v[i].first<<'\n';
}
cnt++;
}
}
後進先出(LIFO)
有點像堆疊 書堆的概念
或是一個乒乓球桶的感覺
常用功能:
push()
pop()
top()
stack<資料型態>名稱;
stack<int>st;
stack<char>stk;無法預設大小
可以用size()來看有多長
empty()看是否為空
push():從尾端推入元素
pop():從尾端移除元素
在pop的時候
如果不確定大小時
記得要檢查是否為空
否則會出錯(RE)
stack<int>st;
st.push(1);
st.push(2);
st.push(3);
st.pop();
if(!st.empty())st.pop();
無法用[]取值
top():
拿最上面的那個
只能拿最上面那一個
若stack為空也會RE
stack<int>st;
st.push(1);
st.push(2);
st.push(3);
st.pop();
cout<<st.top()<<' ';題目
i213
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
stack<int>st;
for(int i=0;i<n;i++){
int a;cin>>a;
if(a==1){
int b;cin>>b;
st.push(b);
}
else if(a==2){
if(st.empty())cout<<-1;
else cout<<st.top();
cout<<'\n';
}
else{
if(!st.empty())st.pop();
}
}
}
f345
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
stack<int>st;
for(int i=0;i<n;i++){
int a;cin>>a;
st.push(a);
}
while(!st.empty()){
cout<<st.top()<<' ';
st.pop();
}
}
先進先出(FIFO)
排隊的概念
跟stack有相反的感覺
常用功能:
push()
pop()
front()
queue<資料型態>名稱;
queue<int>q;
queue<char>qq;和stack基本一樣
無法預設大小
size()看有多長
empty()檢查是否為空
push():從尾端推入元素
pop():從最前端移除元素
queue<int>q;
q.push(1);
q.push(2);
q.push(3);
q.pop();
if(!q.empty())q.pop();pop的時候一樣要注意是否為空
front():取最前面元素
queue<int>q;
q.push(1);
q.push(2);
q.push(3);
q.pop();
cout<<q.front<<' ';
if(!q.empty())q.pop();
pop的時候一樣要注意是否為空
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;cin>>n;
queue<int>q;
for(int i=0;i<n;i++){
int a;cin>>a;
if(a==1){
int b;cin>>b;
q.push(b);
}
else if(a==2){
if(q.empty())cout<<-1;
else cout<<q.front();
cout<<'\n';
}
else{
if(!q.empty())q.pop();
}
}
}
怎麼唸?
dq?
deck
雙端佇列
(double-ended queue)
stack+queue
方法跟前面兩個基本差不多
直接放code
#include<bits/stdc++.h>
using namespace std;
int main(){
deque<int>dq;
deque<char>dq1;
}雙向=可從頭尾加入移除元素
push_back(),pop_back():從後端增減元素
push_front(),pop_front:從前端加減元素
#include<bits/stdc++.h>
using namespace std;
int main(){
deque<int>dq;
dq.push_front(1);
dq.push_back(2);
dq.push_back(3);
dq.pop_back();
dq.pop_front();
}front():最前端元素
back():最後端元素
#include<bits/stdc++.h>
using namespace std;
int main(){
deque<int>dq;
dq.push_front(1);
dq.push_back(2);
dq.push_back(3);
cout<<dq.front()<<dq.back();
}empty():判斷是否為空
size():回傳大小
#include<bits/stdc++.h>
using namespace std;
int main(){
deque<int>dq;
dq.push_front(1);
dq.push_back(2);
dq.push_back(3);
if(dq.empty())cout<<"empty!\n";
cout<<dq.size();
}各個操作都比vector慢3倍
沒事不要用到它
沒事不要用到它
沒事不要用到它
開stack跟queue的時候其實都是在開一個deque
所以速度上stack=queue=deque
如果要練習的話
就用deque把前面的題目寫一次
集合
裡面元素都是唯一(不重複)
且都排序好的
實作方式 紅黑樹
很難很複雜(我不會)
set<int>s;
set<char>st;就像一個黑盒子
1.可以放東西進去
2.拿東西出來
3.詢問一個東西是否在裡面
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
st.erase(1);
insert():放入東西
erase():移除東西
把1移除
裡面剩下2 3
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
if(st.find(2)!=st.end())cout<<"Yes\n";
if(st.count(2))cout<<"Yes\n";
if(st.empty())cout<<"empty";
find():如果找到 回傳記憶體位置
(如果沒找到 回傳end())
count():裡面有幾個
empty():是否為空
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
auto it=st.find(2);
//auto=set<int>::iterater
if(it!=st.end())cout<<*it;
find()回傳的是記憶體位置
輸出位置的值的話加個*
不知道各位有沒有忘記它
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
auto it=st.begin(2);
//auto=set<int>::iterater
cout<<*it<<'\n';
cout<<*next(it)<<'\n';
cout<<*prev(it)<<'\n';
begin(),end()
prev():此記憶體位置的前一項
next():此記憶體位置的前一項
可以不用修改it的值
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
auto it=st.begin();
//auto=set<int>::iterater
cout<<*next(it)<<'\n';
cout<<*(++it)<<'\n';
如何用set輸出第2小的數字?
set裡面的元素是有序的
第二大=第二個元素
可以思考一下兩種輸出有什麼差別
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
for(int i:st)cout<<i<<'\n';
for(auto iter=st.begin();iter!=s.end();iter++){
cout<<*iter<<'\n';
}
跟vector差不多
一般用上面那種
set<int>st;
st.insert(1);
st.insert(2);
st.insert(3);
cout<<*st.upper_bound(2);
set有upper_bound()函式
.upper_bound(k)尋找第一個大於k的位置
注意 是位置 值的話*
(為甚麼說"也有" 因為我還沒講)
set一種元素只能存一個
不夠 要更多?
STL有個東西叫做Multiset
可以同時存在多個相同元素
與set語法大致相同
1.count():可回傳元素數量
2.erase(n):刪除所有為n的元素
只刪除一個:s.erase(s.find(10))
multiset<int>st;
st.insert(1);
st.insert(1);
st.insert(2);
st.insert(3);
cout<<st.count(1)<<'\n';
只要知道元素是否在裡面
不用排序?
STL 還有個東西是unordered_set !!!
功能如其名
底層用hash實作
失去upper_bound功能
整體比set快
有時候可以拿來優化
(還有unordered_multiset)
目前用法最特殊的
功能也一堆
不過多寫點題目
每次反覆使用
就可以輕鬆拿捏
Set挺重要的
想法:
輸出大小
按照順序輸出
相同的去掉
用set
#include<bits/stdc++.h>
using namespace std;
int main(){
set<int>st;
int n,a;
cin>>n;
for(int i=0;i<n;i++){
cin>>a;
st.insert(a);
}
cout<<st.size()<<'\n';
for(auto x:st){
cout<<x<<' ';
}
}想法:
不同值的數量
有點像...
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
set<int>s;
for(int i=0;i<n;i++){
int a;
cin>>a;
s.insert(a);
}
cout<<s.size();
}
沒錯 set的大小
想法:
用set來檢查是否出現過
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,c=1;
while(cin>>n){
int arr[1005];
set<int>st;
for(int i=0;i<n;i++){
cin>>arr[i];
}
bool flag=1;
for(int i=0;i<n-1;i++){
for(int j=i;j<n;j++){
int tmp=arr[i]+arr[j];
if(st.count(tmp)){
flag=0;
break;
}
st.insert(tmp);
}
if(!flag)break;
}
if(flag)cout<<"Case #"<<c<<": It is a B2-Sequence.\n";
else cout<<"Case #"<<c<<": It is not a B2-Sequence.\n";
c++;
}
}
count()>0代表出現過
可以用unordered_set
想法:
陣列操作(複雜)
用set來計算種類數
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
set<char>st;
int dx[6]={-1,0,1,1,0,-1};
int dy[6]={0,1,1,0,-1,-1};
int main(){
string s="";
cin>>n>>m>>k;
char v[25][25];
for(int i=0;i<n;i++){
string b;
cin>>b;
for(int j=0;j<m;j++){
v[i][j]=b[j];
}
}
int x=n-1,y=0;
for(int i=0;i<k;i++){
int a,tx,ty;
cin>>a;
tx=x+dx[a];
ty=y+dy[a];
if((tx<n&&tx>=0)&&(ty<m&&ty>=0)){
x+=tx-x;
y+=ty-y;
}
st.insert(v[x][y]);
s+=v[x][y];
}
cout<<s<<'\n';
cout<<st.size();
}count()>0代表出現過
可以用unordered_set
想法:
陣列操作(複雜)
用set來計算種類數
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
set<char>st;
int dx[6]={-1,0,1,1,0,-1};
int dy[6]={0,1,1,0,-1,-1};
int main(){
string s="";
cin>>n>>m>>k;
char v[25][25];
for(int i=0;i<n;i++){
string b;
cin>>b;
for(int j=0;j<m;j++){
v[i][j]=b[j];
}
}
int x=n-1,y=0;
for(int i=0;i<k;i++){
int a,tx,ty;
cin>>a;
tx=x+dx[a];
ty=y+dy[a];
if((tx<n&&tx>=0)&&(ty<m&&ty>=0)){
x+=tx-x;
y+=ty-y;
}
st.insert(v[x][y]);
s+=v[x][y];
}
cout<<s<<'\n';
cout<<st.size();
}count()>0代表出現過
可以用unordered_set
前面教過陣列取值
int arr[105];
arr[5]=3;
cout<<arr[5]<<'\n';陣列名稱[索引值]
索引5 對應到的值是3
那今天如果索引值不是整數?
只有辦法從0到陣列大小-1嗎?
那肯定是可以的
map就是在做這件事
map<int,int>mp;//宣告
map<string,int>mp1;
map<string,string>mp2;map能夠將一個鍵(key)
對應到一個值(value)
可以把它當查資料
輸入書名 告訴你作者是誰
map<int,int>mp;//宣告
map<string,int>mp1;
mp[5]=3;
mp[3]++;
mp1["abc"]=100;
mp.erase(5);//刪除如果key存在 修改它的值
否則新增一個key
一個新的key預設值
整數是0
字串是""
map<int,int>mp;//宣告
mp[5]=3;
cout<<mp[5]<<'\n';
cout<<mp[0]<<'\n';如果key存在 輸出它的值
否則新增一個value是預設值的key
所以mp[0]是0
map<int,int>mp;//宣告
mp[5]=3;
mp[0]=10;
for(pair<int,int> i:mp){
cout<<i.first<<' '<<i.second<<'\n';
}會按照key的值由小到大排
型態是pair
first是key
second是value
pair太長了 寫auto比較簡略
底層結構是紅黑樹
跟set一樣
插入、刪除、查詢的時間複雜度
都是O(log n) n是map大小
如果key不想要排序?
實作方式改為hash
失去順序
插入、查詢、刪除的複雜度變成O(1)
#include<bits/stdc++.h>
using namespace std;
int main(){
unordered_map<string,string>mp;
mp["HELLO"]="ENGLISH";
mp["HOLA"]="SPANISH";
mp["HALLO"]="GERMAN";
mp["BONJOUR"]="FRENCH";
mp["CIAO"]="ITALIAN";
mp["ZDRAVSTVUJTE"]="RUSSIAN";
int t=1;
string s;
while(cin>>s && s!="#"){
cout<<"Case "<<t<<": ";
if(mp[s]!="")cout<<mp[s]<<'\n';
else cout<<"UNKNOWN\n";
t++;
}
}
基本的查詢
#include<bits/stdc++.h>
using namespace std;
int main(){
string s,a;
map<string,int>m{
{"B",1},{"F",1},{"P",1},{"V",1},
{"C",2},{"G",2},{"J",2},{"K",2},{"Q",2},{"S",2},{"X",2},{"Z",2},
{"D",3},{"T",3},
{"L",4},
{"M",5},{"N",5},
{"R",6}
};
int x=0;
while(cin>>s){
for(int i=0;i<s.size();i++){
a=s[i];
if(m[a]==0){
x=0;
continue;
}
else if(m[a]==x)continue;
else x=m[a];
cout<<x;
}
cout<<'\n';
}
}另一種建立key value的方式
其他都基本操作
#include<bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0);
int n;
while(cin>>n){
string s;
int x=1;
map<string,int>m;
for(int i=1;i<=n;i++){
cin>>s;
if(m[s]!=0){
cout<<"Old! "<<m[s]<<'\n';
}
else{
m[s]=x;
x++;
cout<<"New! "<<m[s]<<'\n';
}
}
}
}利用map記第幾個
功能:將數字丟進去,由大排到小
可以查詢最大值
可以刪除最大值
優先隊列
priority_queue<int>pq;如果想要由小排到大
priority_queue<int,vector<int>,greater<int>>pq;priority_queue<int>pq;
pq.push(3);
pq.push(5);
pq.push(4);
pq.push(1);
pq.pop();
pq.push(2)push():加入一個數字
pop():刪除最大值
priority_queue<int>pq;
pq.push(3);
pq.push(5);
pq.push(4);
cout<<pq.top();top():查詢最大值
priority_queue<int>pq;
pq.push(3);
pq.push(5);
pq.push(4);
cout<<pq.size();
if(!pq.empty())cout<<pq.top();empty():回傳是否為空
size():回傳大小
實作是用heap
資芽會教 去報名
複雜度雖然跟set一樣(O(log(n))
但常數比較小
有很多greedy的題目會用到
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
int n,a;
priority_queue<ll,vector<ll>,greater<ll>>pq;
while(cin>>n &&n!=0){
ll ans=0;
for(int i=0;i<n;i++){
cin>>a;
pq.push(a);
}
while(pq.size()>1){
int a,b,cost;
a=pq.top();
pq.pop();
b=pq.top();
pq.pop();
cost=a+b;
ans+=cost;
pq.push(cost);
}
cout<<ans<<'\n';
pq.pop();
}
}bool arr[10005];裡面都存布林值(0,1)
特別優化過的布林陣列
空間跟時間都有優化
尤其是時間
<>裡面放的是大小
bitset<100005>bs;開一個大小為100005的陣列
bitset<100005>bs;
b[3]=1;//第四項為true
b[2]=1;
cout<<b[1];和布林陣列一樣
bitset<100005>bs;
b[3]=1;//第四項為true
b[2]=1;
cout<<b.count();
b.reset();
b.set();count():回傳裡面1的數量
set():全部設成1
reset():全部設成0
bitset可以進行位元運算
速度極快
大概是正常的1/32倍
所以有些題目可以用bitset優化
但那些題目挺難
之後有機會可以分享
遇到布林陣列的題目或位元運算操作的題目可以用bitset練習看看
用來求最小最大值
int a=10,b=5,c=11;
cout<<min(a,b);
cout<<max(b,c);
cout<<max({a,b,c});
//3個數字加大括號要注意不同型別不能比較
long long跟int不能放一起
int a=10;
long long b=5;
cout<<min((long long)a,b);
//強制轉型
絕對值
int a=10,b=-10;
cout<<abs(a)<<'\n';
cout<<abs(b)<<'\n';回傳的型態跟傳入值一樣
交換兩數
int a=10,b=130;
cout<<a<<' '<<b<<'\n';
swap(a,b);
cout<<a<<' '<<b<<'\n';之前排序的code也有
可以交換陣列的兩項
開根號
int a=100,b=15;
cout<<sqrt(a)<<'\n';
cout<<sqrt(b)<<'\n';回傳型態跟輸入值相同
複雜度:
pow(a,b)回傳a的b次方
int a=2,b=15;
cout<<pow(a,b)<<'\n';複雜度不一定 雖然底層是用快速冪
但聽說因為很慢 被叫慢速冪
用浮點數運算
會有誤差 別用
__gcd(a,b)回傳a,b的最大公因數
int a=243,b=15;
cout<<__gcd(a,b)<<'\n';複雜度:
__lg(a)回傳a以2為底取對數值
int a=1024;
cout<<__lg(a)<<'\n';複雜度:
傳入必須是整數
回傳會取整
回傳以e為底的對數值
int a=50;
cout<<log(a)<<'\n';複雜度:
浮點數運算
sort(a,b)
將a位置(包含)到b位置(不包含)元素由小到大排
int arr[4]={3,2,1,4};
sort(arr,arr+4);
for(int i=0;i<4;i++){
cout<<arr[i]<<' ';
}複雜度:
開始 結束
隱藏參數?
sort(a,b,cmp)
cmp如果回傳false則交換
bool cmp(int a,int b){
return a>b;
}從大排到小
也有其他種 比如二維點或其他種structure
greater<int>()
reverse(a,b)
將a位置(包含)到b位置(不包含)元素反轉
int arr[4]={3,2,1,4};
reverse(arr+1,arr+4);
for(int i=0;i<4;i++){
cout<<arr[i]<<' ';
//3 4 1 2
}字串蠻常用到的
min/max_element(a,b)
回傳a位置(包含)到b位置(不包含)最小/大值的指標
int arr[4]={3,2,1,4};
cout<<*min_element(arr,arr+4)<<'\n';
cout<<min_element(arr,arr+4)-arr;找到的位置-第一項的位置=它的index
fill(a,b,c)
回傳a位置(包含)到b位置(不包含)的值變成c
int arr[4]={3,2,1,4};
fill(arr,arr+3,6767);
for(int i=0;i<4;i++){
cout<<arr[i]<<' ';
}可用於初始化陣列
lower_bound(a,b,c)
回傳a位置(包含)到b位置(不包含)第一個>=c的位置
int arr[4]={-10,2,12,48};
sort(arr,arr+4);
cout<<*lower_bound(arr,arr+4,3)回傳b的話 代表沒找到
要再由小到大排的陣列才可使用
upper_bound(a,b,c)
回傳a位置(包含)到b位置(不包含)第一個>c的位置
int arr[4]={-10,2,12,48};
sort(arr,arr+4);
cout<<*upper_bound(arr,arr+4,3)回傳b的話 代表沒找到
要再由小到大排的陣列才可使用
有時候題目一直TLE
卻想不到怎麼優化
輸入量又很大
怎麼辦
IO優化!
ios::sync_with_stdio(0),cin.tie(0);
可以當成模板打
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0);
}放在main函式裡面
可以加速輸入輸出
ios::sync_with_stdio(0),cin.tie(0);
可以當成模板打
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(0),cin.tie(0);
}放在main函式裡面
可以加速輸入輸出
但是打上去後cin就不能和scanf混用
sync_with_stdio(0)
如何優化的?
會關閉cin cout scanf printf 的同步
減少性能損失
所以打了之後不能混用
cin.tie(0)
如何優化的?
當電腦cin的時候 會刷新緩衝區
讓輸入前將輸出完成
但就會耗費很多時間
cin.tie(0)
關閉了此動作
所以可以加速
cin.tie(0)
如何優化的?
當電腦cin的時候 會刷新緩衝區
讓輸入前將輸出完成
但就會耗費很多時間
cin.tie(0)
關閉了此動作
所以可以加速
類似一個變數的概念
但它存的是16進位的記憶體位置
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[10] = {2,4,3,5,12,5,23,6,3,6};
cout<<a<<endl;
}去跑跑看
會回傳a[0]的記憶體位置
如果知道一個指標
要怎麼知道真正的值
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[10] = {2,4,3,5,12,5,23,6,3,6};
cout<<*a<<endl;
}那如果知道一個值
要怎麼知道它的指標
#include<bits/stdc++.h>
using namespace std;
int main(){
int a = 5;
int *ptr = &a;
cout<<ptr<<endl;
}C++的*有兩種功能
(1)取出指標的值
(2)指標變數
當這個變數要存指標時 就需要加*
#include<bits/stdc++.h>
using namespace std;
int main(){
int a = 5;
int *ptr = &a;
cout<<ptr<<endl;
}#include<bits/stdc++.h>
using namespace std;
int main(){
int a = 5;
int *ptr = &a;
cout<<a<<endl;
*ptr = 10;
cout<<a<<endl;
}既然ptr存的是a的記憶體位置
那是不是就可以直接改a的值
#include<bits/stdc++.h>
using namespace std;
int main(){
int a[10] = {23,4,3,5,12,5,23,6,3,6};
cout<<*(a+4)<<endl;
cout<<*(a+7)<<endl;
}好想有點似曾相識?
int main(){
int a[10] = {23,4,3,5,12,5,23,6,3,6};
cout<<*(a+4)<<endl;
cout<<*(a+7)<<endl;
cout<<a[4]<<endl;
cout<<a[7]<<endl;
}沒錯 跟[]是一模一樣的東西
小結:
非常抽象
是個很厲害很好用的工具
linked list,動態開點線段樹...
還有一堆極抽象的東西
在高中競程用的比較少
我有很熟