简易模板汇总
1.c++高精度
http://blog.csdn.net/code4101/article/details/23020525
手写高精度乘法
#include<bits/stdc++.h> using namespace std; string a1,b1; int jw=0,lena,lenb,lenc,a[2005],b[2005],c[4005];//x位数*y位数最多得出x+y位数,给数组留5左右的空间; int main() { //freopen(".in","r",stdin); //freopen(".out","w",stdout); cin>>a1>>b1;//读入; lena=a1.length(); lenb=b1.length(); if(a1[0]=='0' || b1[0]=='0') { cout<<0; return 0; } //判断0的情况; if(lena<lenb || (lena==lenb&&a1[0]<b1[0])) { swap(a1,b1); swap(lena,lenb); } //把较小的数放在b1,提高效率; if(a1[0]=='-'&&b1[0]!='-') { cout<<"-"; a1[0]=' '; b1=' '+b1; } if(b1[0]=='-'&&a1[0]!='-') { cout<<"-"; b1[0]=' '; a1=' '+a1; } if(a1[0]!='-'&&b1[0]!='-') { a1=' '+a1; b1=' '+b1; } if(a1[0]=='-'&&b1[0]=='-') { a1[0]=' '; b1[0]=' '; } //判断一下负数,a1[0] 和 b1[0]判断,i从1开始 ; for(int i=1;i<=lena;i++) a[i]=a1[lena-i+1]-'0'; for(int i=1;i<=lenb;i++) b[i]=b1[lenb-i+1]-'0';//逆序存储; /*for(int i=1;i<=lena;i++) cout<<a[i]<<" "; cout<<endl; for(int i=1;i<=lenb;i++) cout<<b[i]<<" ";*/ //调试; for(int i=1;i<=lenb;i++) for(int j=1;j<=lena;j++) { c[i+j-1]=c[i+j-1]+(b[i]*a[j]); c[i+j]+=c[i+j-1]/10; c[i+j-1]%=10; } //最关键的一步,模拟乘法竖式计算; //b[i]*a[j]应存放在c[i+j]中,由于数组从1开始,所以-1; int lenc=lena+lenb; while(lenc>0&&c[lenc]==0) { lenc--; } //消去开头的0; for(int i=lenc;i>=1;i--) cout<<c[i]; return 0; }
2.Java高精度
http://blog.csdn.net/piaocoder/article/details/47071935
3.高精度进制转换
https://blog.csdn.net/yew1eb/article/details/10092465
4.判回文数
bool check(ll x) { ll t = x, y = 0; while (t) { y = y * 10 + t % 10; t /= 10; } if (x != y) return 0; return 1; }
5.矩阵快速幂
http://www.cnblogs.com/wxl-Ezio/p/8520427.html
6.最小生成树
https://www.luogu.org/problemnew/show/P3366
这个是kruskal,并查集处理点,路径压缩连点。
#include<bits/stdc++.h> using namespace std; #define MAXN 10000005 int pa[MAXN],ra[MAXN],a[MAXN],n,k,ans,cnt; bool is_prime[MAXN]; vector<int> prime; struct edge { int x,y,z; }mp[MAXN]; int init(int n) { for(int i=1; i<=n; i++) { pa[i]=i; ra[i]=0; } } int Find(int x) { return pa[x]==x ? x : pa[x]=Find(pa[x]); } bool cmp(const edge &x,const edge &y) { return x.z<y.z; } void kruskal() { sort(mp,mp+k,cmp); //排序 for(int i=0;i<k;i++) { int x=Find(mp[i].x),y=Find(mp[i].y); //取出根节点 if(x==y) continue; //如果已经加入集合就跳过 ans+=mp[i].z; pa[y]=x; cnt++; //记录节点数 if(cnt==n-1) break; } } int main() { scanf("%d %d",&n,&k); init(n); for(int i=0;i<k;i++) scanf("%d %d %d",&mp[i].x,&mp[i].y,&mp[i].z); kruskal(); if(cnt!=n-1) printf("orz"); else printf("%d",ans); return 0; }
这个是堆优化的prim,邻接表存图,dijkstra的连边。
#include <bits/stdc++.h> using namespace std; typedef pair<int,int>pii; #define INF 2147483647 int d[1000005],vis[1000005],cnt,sum,n,m; vector<pii>e[1000005]; struct cmp //自定义排序方法 因为我定义的优先队列里,边权和是第二个元素,如果直接greater,它会默认按第一个元素排序 { bool operator()(pii &a,pii &b) { return a.second>b.second; } }; priority_queue <pii,vector<pii>,cmp > q; void add_edge(int x, int y, int z) //邻接表存图 { e[x].push_back(make_pair(y, z)); e[y].push_back(make_pair(x, z)); } void init(int n) { for (int i = 1; i <= n; i++) e[i].clear(); //初始化 for (int i = 1; i <= n; i++) d[i] = INF; } void prim() { d[1]=0; q.push(make_pair(1,0)); while(!q.empty()&&cnt<n) { int now=q.top().first; int dis=q.top().second; q.pop(); if(vis[now]) continue; cnt++; sum+=dis; vis[now]=1; for(int i=0; i<e[now].size(); i++) //可以把这个i声明成register类型 提高效率 { int v=e[now][i].first; if(d[v]>e[now][i].second) { d[v]=e[now][i].second; q.push(make_pair(v,d[v])); } } } } int main() { scanf("%d%d",&n,&m); init(n); for(int i=1; i<=m; i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add_edge(x,y,z); } prim(); if (cnt==n) printf("%d",sum); else printf("orz"); }
7.并查集
https://www.luogu.org/problemnew/show/P3367
int init(int n) //初始化 { for(int i=0; i<n; i++) { pa[i]=i; ra[i]=0; } } int Find(int x) //查询 { return pa[x]==x ? x : pa[x]=Find(pa[x]); } bool same(int x,int y) //判断x和y两元素是否在一个集合内 { return Find(x)==Find(y); } void unite(int x,int y) //合并x和y所属的集合 { x=Find(x); y=Find(y); if(x==y) return; if(ra[x]<ra[y]) pa[x]=y; else { pa[y]=x; if(ra[x]==ra[y]) ra[x]++; } }