轉載請註明出處,部份內容引自html
liusu201601大佬數組
首先來一張圖,很直觀(截止到2012年數據)數據結構
下面是收集的一些,我改了一下函數
加粗表示特別重要,必須掌握
其餘表示最好掌握,可能性不是很大,可是某些能夠提升程序效率
學習
高精度
a.加法
b.減法
c.乘法(應該只會有高精乘單精)
d.高精度除單精 (後面c,d考的可能性較小,應該只考a,b)優化
排序算法
a.選擇排序
b.插入排序
c.hash排序
d.歸併排序(單純的排序可能用不到,有快排就好了,可是歸併排序的思想很重要)
e.堆排序
f.快排spa
字符串匹配算法
a.蠻力法
b.KMP.net
數論
a.歐幾里德算法(用展轉相除法求最大公約數)
b.擴展歐幾里德算法 ax+by=c 的正整數
c.素數 O(sqrt(n))
d.篩法求素數
e.快速乘方(位運算+同餘+高精)code
樹論
a.二叉搜索樹
b.優先隊列(C++中priority_queue,至關於手動維護的小(大)根堆的數據結構優化)
c.線段樹 (RMQ問題建議使用st算法)
d.平衡樹一種(建議學習SBT)
圖論
a.拓撲排序
b.割頂,割邊(橋) {O(n)}
c.強連通分支 O(n)
d.有向無迴路圖的最長路徑
e.歐拉回路
f.最小生成樹
① Prime O(N2)
② Kruskal O(M2)
g.次小生成樹 {簡單的刪除最大邊是不對的}
h.最短路徑
① Dijkstra
② Bellman-ford
③ spfa
④ flyod
單源點最短路徑算法推薦使用spfa(即便你習慣dijkstra),Dijkstra不能有負邊不能有迴路,因此用spfa更保險
計算幾何
a.判斷兩條線段是否相交
b.凸包算法 O(n)
其餘算法
a.並查集
b.RMQ
......
高精度算法
一、高精度加法(簡單版,以noi1.6:10大整數加法題爲例)
//noi1.6:10大整數加法 //題解:高精度入門題:結構體+字符轉換+進位 #include<cstdio> #include<cstring> struct nod{int n,a[210];nod(){memset(a,0,sizeof(a));}}a,b; char s[210]; int main() { int ns;//讀入a============ scanf("%s",s+1);//下標從1開始 ns=strlen(s+1); a.n=ns; for(int i=1;i<=ns;i++)//字符逆序轉換爲數字 {//爲了數位 對齊,翻轉數字 a.a[ns-i+1]=s[i]-'0'; }//======================== //讀入b==================== scanf("%s",s+1);//下標從1開始 ns=strlen(s+1); b.n=ns; for(int i=1;i<=ns;i++)//字符逆序轉換爲數字 {//爲了數位 對齊,翻轉數字 b.a[ns-i+1]=s[i]-'0'; }//========================= //模擬加法運算 a.n=a.n>b.n?a.n:b.n;//肯定數位 for(int i=1;i<=a.n;i++)//暴力加 { a.a[i]+=b.a[i]; } for(int i=1;i<=a.n;i++)//處理進位 { if(a.a[i]>9) { a.a[i+1]+=a.a[i]/10;//向右進位 a.a[i]%=10;//保留個位數 if(i==a.n) a.n++;//最高位溢出 } } //消除前導0 while(a.a[a.n]==0&&a.n>1) a.n--;//最高位必須非0 //反向輸出 for(int i=a.n;i>=1;i--) { printf("%d ",a.a[i]); } return 0; }
二、高精度減法(簡單版,以noi1.6:11大整數減法題爲例)
//noi1.6:11大整數減法 //題解:高精度入門題:結構體+字符轉換+借位 #include<cstdio> #include<cstring> struct nod{int n,a[210];nod(){memset(a,0,sizeof(a));}}a,b; char s[210]; int main() { int ns;//讀入a============ scanf("%s",s+1);//下標從1開始 ns=strlen(s+1); a.n=ns; for(int i=1;i<=ns;i++)//字符逆序轉換爲數字 {//爲了數位 對齊,翻轉數字 a.a[ns-i+1]=s[i]-'0'; }//======================== //讀入b==================== scanf("%s",s+1);//下標從1開始 ns=strlen(s+1); b.n=ns; for(int i=1;i<=ns;i++)//字符逆序轉換爲數字 {//爲了數位 對齊,翻轉數字 b.a[ns-i+1]=s[i]-'0'; }//========================= //模擬減法運算 for(int i=1;i<=a.n;i++) a.a[i]-=b.a[i];//暴力減 for(int i=1;i<=a.n;i++)//處理借位 { if(a.a[i]<0) { a.a[i+1]-=1;//向右借 1 a.a[i]+=10;//補充數值 } } //消除前導0//本題保證a>b,若是不知道大小關係呢? while(a.a[a.n]==0&&a.n>1) a.n--;//最高位必須非0 //反向輸出 for(int i=a.n;i>=1;i--) printf("%d",a.a[i]); return 0; }
三、高精度乘法(有兩種:高精度*低精度,高精度*高精度)
(如下代碼只展現高精度*低精度,以noi1.6:12:計算2的N次方 題爲例)
//noi1.6:12計算2的N次方 //題解:高精度*低精度 +非結構體 +函數 #include<cstdio> int a[1010],na;//估算數組,2的100次不知道是多少位? //10的100次是1000位,能夠了嗎? void cf(int x) { for(int i=1;i<=na;i++)//每位都乘 { a[i]*=x; } for(int i=1;i<=na;i++)//處理進位 { if(a[i]>9) { a[i+1]+=a[i]/10; a[i]%=10; if(i==na) na++;//最高位溢出 } } } int main() { int n; scanf("%d",&n); a[1]=1;na=1; for(int i=1;i<=n;i++) { cf(2); } for(int i=na;i>=1;i--) printf("%d",a[i]);//反向輸出 //如今你能夠知道2的100次方是多少位了嗎? return 0; }
四、高精度除法(有兩種:高精度/低精度,高精度/高精度)
(如下代碼只展現高精度/低精度,以noi1.6:13:大整數的因子 題爲例)
//noi1.6:13大整數的因子 //題解:高精度除以低精度:模擬思想 #include<cstdio> #include<cstring> char s[210]; int a[210],na,ls=0; void chu(int x) { int k=0;//餘數 for(int i=na;i>=1;i--)//模擬豎式除法 { k=k*10+a[i]; k=k%x; } if(k==0) { ls=1; //打標籤 printf("%d ",x); } } int main() { int ns; scanf("%s",s+1);//下標從1開始 ns=strlen(s+1); na=ns; for(int i=1;i<=ns;i++)//字符逆序轉換爲數字 { a[ns-i+1]=s[i]-'0'; } for(int i=2;i<=9;i++) { chu(i);//函數處理 } if(ls==0) printf("none"); return 0; }