2020解題記錄
阿新 • • 發佈:2020-11-23
11.15 樹
- 小球-drop
- 大事化小,n層化n-1層,計算進入該結點的次數
- 二叉樹遍歷-flist
- 中序+層序==前序
- 遞迴+按層遍歷=前序遍歷
- rank表,尋找最小結點
- 子樹上結點號最小的結點是子樹的根結點
- FBI樹
- 同時進行遞迴計算FBI和後序遍歷
- 猜數字
cout<<(min+max)/2<<endl;
- 人以群分
- 單調序列
- 最小環
- gcd多個最小環
- 物以類聚(如1、3、5、6、4、2)
11.17 樹+堆
超級對拍程式
rem Name: Batch For Check rem Copyright: All Right Reservedrem Author: Chen Jie rem Date: 2020/10/17 rem Description: RENAME the *.bat file and run it. rem The batch will consider succesive spaces as one. @echo off ::no parameter then begin for loop if "%1"=="" goto loop set BAT_NAME=%~nx0 ::BAT_NAME=TFILE_NAME.bat set FILE_NAME=%BAT_NAME:~0,-4% ::if no exist the corresponding input file, then end the batchif not exist %FILE_NAME%%1.in ( goto end ) if exist %FILE_NAME%%1.out ( set ANS_NAME=%FILE_NAME%%1.out ) if exist %FILE_NAME%%1.ans ( set ANS_NAME=%FILE_NAME%%1.ans ) copy %FILE_NAME%%1.in %FILE_NAME%.in >nul echo Problem Test Data %1 time<enter %FILE_NAME% < %FILE_NAME%.in > %FILE_NAME%.out time<enter ::if exist error, then pause for showing the difference fc %FILE_NAME%.out %ANS_NAME% /w /n if errorlevel 1 ( pause>nul ) del %FILE_NAME%.in del %FILE_NAME%.out ::end the batch goto end :loop ::call the corresponding data batch for %%i in (0 1 2 3 4 5 6 7 8 9 10 11) do call %0 %%i echo Press Any Key To Exit ... pause>nul :end
就地建堆函式
- make_heap(),pop_heap(),push_heap()
C++中的make_heap(), pop_heap()的標頭檔案為<algorithm>。作用與priority_queue<>;中的成員函式相同,可以單獨使用。
make_heap(begin,end,greater<int>());
在容器範圍內,就地建堆,保證最大值在所給範圍的最前面,其他值的位置不確定pop_heap(begin,end,greater<int>());
將堆頂(所給範圍的最前面)元素移動到所給範圍的最後,並且將新的最大值置於所給範圍的最前面push_heap(begin,end,greater<int>());
當已建堆的容器範圍內有新的元素插入末尾後,應當呼叫push_heap將該元素插入堆中。
code到word帶格式複製
- 二叉樹輸出(btout)
- 一個數組能解決的事不要用結構體
- 查詢二叉樹(tree_a)
- 對稱二叉樹(tree_c)
- 合併果子(fruit)
11.18 堆+圖
最小字典序Euler迴路(逆序)
- 騎馬修柵欄(fence)
void find(int now) { for (int k = mi; k <= ma; k++) if (available[now][k] > 0) { available[now][k]--; available[k][now]--; find(k); } c[++cnt] = now; }
命令引數
-
VS2019-專案-屬性-除錯-命令引數
- 命令列格式指定輸入檔案
< $(ProjectDir)$(Configuration)\$(ProjectName).in
- 命令列格式指定輸入檔案
-
基於紅黑樹的可重複集合
multiset<int>st; st.insert(a); cout << *st.begin() << ' '; st.erase(st.begin()); cout << *(--st.end()) << endl; st.erase(--st.end());
-
看病-hp
- release比debug快,約
4~6~9
倍 - 簡單的程式倍數高
0.11-0.96 0.7-4 1.4-5.77
- release比debug快,約
-
小明的賬單-bill
- heap不會錯
- multiset太慢
-
鏟雪車(snow)
- 加起來就好了,別多想
-
珍珠(bead)
- 不允許指向引用的指標、迭代器,即不允許定義
vector<typename&>vec;
- 不允許指向引用的指標、迭代器,即不允許定義
11.19 第三節 最短路徑演算法
FloyedΘ(N3)Floyed \Theta(N^3)FloyedΘ(N3)
- 適用於出現負邊權的情況
初始化:點u、v如果有邊相連,則dis[u][v]=w[u][v]。 如果不相連則dis[u][v]=INT_MAX
for (k = 1; k <= n; k++) for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) if (dis[i][j] > dis[i][k] + dis[k][j]) dis[i][j] = dis[i][k] + dis[k][j];
- 牛的旅行-travel
這兩個牧場都在John的農場上。John將會在兩個牧場中各選一個牧區,然後用一條路徑連起來,使得連通後這個新的更大的牧場有最小的直徑。注意,如果兩條路徑中途相交,我們不認為它們是連通的。只有兩條路徑在同一個牧區相交,我們才認為它們是連通的。 現在請你程式設計找出一條連線兩個不同牧場的路徑,使得連上這條路徑後,這個更大的新牧場有最小的直徑。 用Floyed求出任兩點間的最短路,然後求出每個點到所有可達的點的最大距離,記做mdis[i]。(Floyed演算法) r1=max(mdis[i]); 然後列舉不連通的兩點i,j,把他們連通,則新的直徑是mdis[i]+mdis[j]+(i,j)間的距離。 r2=min(mdis[i]+mdis[j]+dis[i,j]); re=max(r1,r2);//舊最大與新直徑的最小的最大 re就是所求。
DijkstraΘ(N2)Dijkstra \Theta(N^2)DijkstraΘ(N2)
- 不能處理存在負邊權的情況
設起點為s,dis[v]表示從s到v的最短路徑,pre[v]為v的前驅節點,用來輸出路徑。 a)初始化:dis[v]=∞(v≠s); dis[s]=0; pre[s]=0; b)For (i = 1; i <= n ; i++) 1.在沒有被訪問過的點中找一個頂點u使得dis[u]是最小的。 2.u標記為已確定最短路徑 3.For與u相連的每個未確定最短路徑的頂點v if (dis[u] + w[u][v] < dis[v]) { dis[v] = dis[u] + w[u][v]; pre[v] = u; } c)演算法結束:dis[v]為s到v的最短距離;pre[v]為v的前驅節點,用來輸出路徑。
for (int i = 1; i <= n; ++i) { int k = 0; for (int j = 1; j <= n; ++j) if (!ok[j] && ans[j] < ans[k]) k = j; if (!k)break; ok[k] = true; for (int j = 1; j <= n; ++j) if (!ok[j] && ratio[j][k]) ans[j] = std::min(ans[j], ans[k] * ratio[j][k]); }
Bellman−FordΘ(NE)Bellman-Ford \Theta(NE)Bellman−FordΘ(NE)
- 能夠處理存在負邊權的情況,但無法處理存在負權迴路的情況
設s為起點,dis[v]即為s到v的最短距離,pre[v]為v前驅。w[j]是邊j的長度,且j連線u、v。 初始化:dis[s]=0, dis[v]=∞(v≠s),pre[s]=0 For (i = 1; i <= n-1; i++) For (j = 1; j <= E; j++)//注意要列舉所有邊,不能列舉點。 if (dis[u] + w[j] < dis[v])//u、v分別是這條邊連線的兩個點。 { dis[v] = dis[u] + w[j]; pre[v] = u; }
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { dis[f[j].y] = std::min(dis[f[j].y], dis[f[j].x] + f[j].w); dis[f[j].x] = std::min(dis[f[j].x], dis[f[j].y] + f[j].w); }
SPFAΘ(kE)SPFA \Theta(kE)SPFAΘ(kE)
- Bellman−FordBellman-FordBellman−Ford演算法的佇列實現
- kkk的平均值是2
dis[i]記錄從起點s到i的最短路徑,w[i][j]記錄連線i,j的邊的長度。pre[v]記錄前趨。 team[1..n]為佇列,頭指標head,尾指標tail。 布林陣列exist[1..n]記錄一個點是否現在存在在佇列中。 初始化:dis[s]=0,dis[v]=∞(v≠s),memset(exist,false,sizeof(exist)); 起點入隊team[1]=s; head=0; tail=1;exist[s]=true; do { 1、頭指標向下移一位,取出指向的點u。 2、exist[u]=false;已被取出了佇列 3、For與u相連的所有點v//注意不要去列舉所有點,用陣列模擬鄰接表儲存 if (dis[v]>dis[u]+w[u][v]) { dis[v]=dis[u]+w[u][v]; pre[v]=u; if (!exist[v])//佇列中不存在v點,v入隊。 { //尾指標下移一位,v入隊; exist[v]=true; } } } while (head < tail);
dis[i] = 0; team[0] = i; int head = 0, tail = 1; exist[i] = true; do { int u = team[head]; if (++head == 2 * 牧場)head = 0; exist[u] = false; for (int j = 1; j <= num[u]; ++j) { int v = a[u][j]; if (dis[v] > dis[u] + w[u][v]) { dis[v] = dis[u] + w[u][v]; if (!exist[v]) { team[tail] = v; if (++tail == 2 * 牧場)tail = 0; exist[v] = true; } } } } while (head != tail);
11.20
int a[5] = { 1,2,3,4,5 }; int* p = a; &(p + 2);//“&”要求左值 &*(p + 2);//等於a + 2
11.21 第四節 圖的連通性問題
一、判斷圖中的兩點是否連通
- Floyed演算法
- 時間複雜度:Θ(N3)\Theta(N^3)Θ(N3)
- 遍歷演算法
- 時間複雜度:Θ(N2)\Theta(N^2)Θ(N2)
二、最小環問題
最小環就是指在一張圖中找出一個環,使得這個環上的各條邊的權值之和最小。在Floyed的同時,可以順便算出最小環。 記兩點間的最短路為dis[i][j],g[i][j]為邊<i,j>的權值。 for (k = 1; k <= n; k++) { for (i = 1; i <= k - 1; i++) for (j = i + 1; j <= k - 1; j++) answer = min(answer, dis[i][j] + g[j][k] + g[k][i]); for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); } answer即為這張圖的最小環。 一個環中的最大結點為k(編號最大),與它相連的兩個點為i,j,這個環的最短長度為g[i][k]+g[k][j]+(i到j的路徑中,所有結點編號都小於k的最短路徑長度)。 根據Floyed的原理,在最外層迴圈做了k-1次之後,dis[i][j]則代表了i到j的路徑中,所有結點編號都小於k的最短路徑。 綜上所述,該演算法一定能找到圖中最小環。
三、求有向圖的強連通分量
Kosaraju演算法可以求出有向圖中的強連通分量個數,並且對分屬於不同強連通分量的點進行標記。它的演算法描述較為簡單: (1) 第一次對圖G進行DFS遍歷,並在遍歷過程中,記錄每一個點的退出順序。 (2)倒轉每一條邊的方向,構造出一個反圖G’。然後按照退出順序的逆序對反圖進行第二次DFS遍歷。 每次遍歷得到的那些點即屬於同一個強連通分量。
憑本事打的表!!
- 組合數
11.22
- B. Deadline Management
- 輸入不保證有序
pair<int, int>t[N];
- 輸入不保證有序
- C. 撕紙條
- 與順序無關
- 不用儲存陣列
- 與順序無關
- F. 加減乘除
- 函式指標陣列
- 4個if也可
- 用一張牌去匹配另一張牌
bool (*check[4])(int, int) = { check1,check2,check3,check4 };
- 函式指標陣列
QQ截圖複製色號
- 按C複製色號dd,dd,dd,Ctrl+C複製16進位制色號#hhhhhh