各類演算法模板
阿新 • • 發佈:2020-10-07
gcd
輾轉相除法求最大公約數
View Code
或者
View Codeexgcd
擴充套件歐幾里得演算法
給予二整數 a 與 b, 必存在有整數 x 與 y 使得ax + by = gcd(a,b)
int exgcd(int a2,int b2,int &x,int &y) { if(b2==0) { x=1;y=0; return a2; } int ans = exgcd(b2,a2%b2,x,y); double temp=x; x=y; y=temp-a2/b2*y;View Codereturn ans; ///返回的還是最大公約數 但是我們就方便求x和y }
int tocal(int a3,int b3) { int x0,y0; int gcd = exgcd(a3,b3,x0,y0); if(1%gcd!=0) return -1; ///gcd得等於1 ... x0*=1/gcd; b3=abs(b3); int ans = x0%b3; if (ans<=0) ans+=b3; return ans; }View Code
lcm:
int lcm(int a,intView Codeb) { return a * b / gcd(a, b); }
那麼求什麼最大公約數最小公倍數 乘法逆元全都解決了
當然我當時也費盡心思研究了一番 為了RSA加密演算法
01揹包:
有一個容量為V的揹包,現在有n件物品,每件物品所佔空間為w[i],價值為v[i],求 揹包中所裝物品價值最大值
注意每個物品就一件
for(i=1;i<=n;i++) for(j=V;j>=w[i];j--) f[j]=max(f[j],f[j-w[i]]+v[i]);
完全揹包
完全揹包是有n種物品,每種物品可以取無線多件,每件物品所佔空間為w[i],價值為v[i]
for(i=1;i<=n;i++) for(j=w[i];j<=V;j++) f[j]=max(f[j],f[j-w[i]]+v[i]);
高精度加法:
#include<bits/stdc++.h> using namespace std; string a,b; string Precise_add(string a,string b){ int lena=a.length(); int lenb=b.length(); int aa,bb,sum,flag=0; while(lena>0){ aa=a[lena-1]-'0'; if(lenb>0) bb=b[lenb-1]-'0'; else bb=0; sum=aa+bb+flag; if(sum>=10){ a[lena-1]='0'+sum%10; flag=1; } else{ a[lena-1]='0'+sum; flag=0; } lena--; lenb--; } if(flag==1) a="1"+a; return a; } int main(){ cin>>a>>b; if(a.size()<b.size()) swap(a,b); cout<<Precise_add(a,b)<<endl; return 0; }
快速冪演算法:
#include<bits/stdc++.h> #define ll long long using namespace std; ll Q(ll n,ll m){ ll res=1; while(m){ if(1&m) res=res*n; n=n*n; m>>=1; } return res; } int main(){ cout<<Q(5,12)<<endl; return 0; }
DFS
#include<bits/stdc++.h> using namespace std; int a[105][105],b[105][105]; int n,m,startx,starty,endx,endy,ans=999999999; int next[4][2]={{1,0},{0,1},{-1,0},{0,-1}}; void dfs(int x,int y,int step){ if(x==endx&&y==endy){ ans=min(ans,step); return; } for(int i=0;i<4;i++){ int xx=x+next[i][0]; int yy=y+next[i][1]; if(xx<1||xx>n||yy<1||yy>m) continue; if(a[xx][yy]==0&&b[xx][yy]==0){ b[xx][yy]=1; dfs(xx,yy,step+1); b[xx][yy]=0; } } return; } int main(){ cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) cin>>a[i][j]; cin>>startx>>starty>>endx>>endy; dfs(startx,starty,0); cout<<ans; return 0; }
最短路徑(暴力)
for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(e[i][j]>e[i][k]+e[k][j]) e[i][j]=e[i][k]+e[k][j]; } } }
尤拉篩篩素數
#include<bits/stdc++.h> using namespace std; void get_prime(vector<int> & prime,int upper_bound){ // 傳引用 if(upper_bound < 2)return; vector<bool> Is_prime(upper_bound+1,true); for(int i = 2; i <= upper_bound; i++){ if(Is_prime[i]) prime.push_back(i); for(int j = 0; j < prime.size() and i * prime[j] <= upper_bound; j++){ Is_prime[ i*prime[j] ] = false; if(i % prime[j] == 0)break;// 保證了一個數只被篩一次。 } } } int main(){ vector<int> prime; get_prime(prime, 1000); for(vector<int> :: iterator it = prime.begin(); it not_eq prime.end(); it++) cout<<*it<<" "; return 0; }
讀入優化
#include<bits/stdc++.h> using namespace std; int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n; cin>>n; cout<<n; }View Code