2014年9月6日搞到这边吧,初级的刷完了,先停停,中级篇看了下目录,以前都刷过,只是没有系统的刷,准备隔几天再刷,看看java面试宝典去。预计花费10天搞完。囧~
/* */ #include<iostream> using namespace std; /* gcd辗转相除法,欧几里得算法 求解直线上的点,切割最小正方形 */ int gcd(int x,int y){ return y==0?x:gcd(y,x%y); } /* extgcd,扩展欧几里得算法 求解二元一次方程整数解 ax+by=c 返回函数=号右边的解c 囧: int a声明一个int类型,名称叫a int* a 声明一个int指针类型,名称叫a int& a 声明一个int引用类型,名称叫a */ int extgcd(int a,int b,int& x,int& y){ int d=a; if(b!=0){ d=extgcd(b,a%b,y,x); y-=(a/b)*x; } else{ x=1; y=0; } return d; } /* 快速幂运算 x^n mod m */ typedef long long ll; ll mod_pow(ll x,ll n,ll m){ int res=1; while(n>0){ if(n&1) res=res*x%m; //如果n为奇数,原公式乘上x^(2^1),则res*x%m x=x*x%m; n>>=1; //n/2 } return res; } /* 大整数取模 n mod m 1234=(((1*10+2)*10+3)*10)+4 //每个括号内mod m一次,累积即可 */ void big_mod(){ char n[100]; int m; scanf("%s%d",n,&m); int len=strlen(n); int ans=0; for(int i=0;i<len;i++){ ans=(int)(((ll)ans*10+n[i])%m); } printf("%d\n",ans); } /* 0~n以内的素数表 */ bool is_prime(int x){ if(x==2) return true; for(int i=2;i*i<x;i++){ if(x%i==0) return false; } return x!=1; } /* 打素数表 */ void prime(){ int n; int MAXN=1<<10; int prime[MAXN],p=0; bool is_prime[MAXN]; //memset(is_prime,true,sizeof(bool)*MAXN); scanf("%d",&n); for(int i=0;i<n;i++)is_prime[i]=true; is_prime[0]=is_prime[1]=false; for(int i=2;i<n;i++){ if(is_prime[i]){ prime[p++]=i; //存入素数表 for(int j=2*i;j<n;j+=i){ //非素打表 is_prime[j]=false;; } } } for(int i=0;i<p;i++) printf("%d ",prime[i]); } int main(){ printf("%d\n",gcd(4,8)); int x=1,y=1; printf("%d\n",extgcd(4,8,x,y)); //big_mod(); prime(); return 0; }
/* 排序所有的边权,从小到大依次取出 判断是否该边两个节点是否在同一个连通分量 如果不在,合并MST。 */ #include<iostream> using namespace std; const int MAXN=1<<10; struct edge{ int u,v,cost; }; edge es[MAXN]; int V,E; int par[MAXN],rank[MAXN]; int comp(const edge& e1,const edge& e2){ return e1.cost<e2.cost; } void init(int N){ for(int i=0;i<N;i++){ par[i]=i; rank[i]=0; } } int find(int x){ if(par[x]==x) return x; return par[x]=find(par[x]); } bool same(int a,int b){ return find(a)==find(b); } void unite(int a,int b){ a=find(a),b=find(b); if(a==b) return ; if(rank[a]>rank[b]) par[a]=b; else{ par[b]=a; if(rank[a]==rank[b]) rank[a]++; } } int kruskal(){ sort(es,es+E,comp); init(V); int res=0; for(int i=0;i<E;i++){ edge e=es[i]; if(!same(e.u,e.v)){ unite(e.u,e.v); res+=e.cost; } } return res; } int main(){ kruskal(); return 0; }
/* 与dijikstra算法 */ #include<iostream> using namespace std; const int MAXN=1<<10; int mincost[MAXN],cost[MAXN][MAXN]; //mincost[i],x集合到i节点的最小代价 bool used[MAXN]; int V; int INF=(1<<31)-1; int prim(){ fill(mincost,mincost+V,INF); fill(used,used+V,false); mincost[0]=0; int res=0; while(true){ int v=-1; //在非x中选择最小权值的点 for(int i=0;i<V;i++){ if(!used[i]&&(v==-1 || mincost[i]<mincost[v])) v=i; } if(v==-1) break; used[v]=true; res+=mincost[v]; //增加MST权重 //更新X集合,维护mincost for(int u=0;u<V;u++){ mincost[u]=min(mincost[u],cost[v][u]); } } return res; } int main(){ prim(); return 0; }
/* dijkstra算法,选最小点d更新边,即加边操作 适用于无负权的图问题 */ #include<iostream> #include<vector> #include<queue> using namespace std; const int MAXN=1<<10; int cost[MAXN][MAXN];//从u->v的权值 int V,d[MAXN],INF=(1<<31)-1; bool used[MAXN]; int prev[MAXN]; /* d[v],cost[u][v]来存储 */ void dijkstra1(int s){ fill(d,d+V,INF); fill(used,used+V,false); fill(prev,prev+V,-1); d[0]=0; while(true){ int v=-1; //选择一个没有使用的最小值的点 for(int u=0;u<V;u++){ if(!used[u] &&(v==-1 || d[u] <d[v])) v=u; } if(v==-1) break; //未选择出来 used[v]=true; //更新所有的点的最小距离 更新操作太多,浪费时间 for(int u=0;u<V;u++){ d[u]=min(d[u],d[v]+cost[v][u]); prev[u]=v; } } } vector<int> get_path(int t){ vector <int >path; for(;t!=-1;t=prev[t]) path.push_back(t); reverse(path.begin(),path.end()); return path; } /* 采用邻接表+堆[查找最小值],复杂度ElogV */ struct edge{ int to,cost; }; vector<edge> G[MAXN]; typedef pair<int ,int> P; // first 代表最短距离,second代表顶点编号 void dijkstra2(int s){ priority_queue<P, vector<P>, greater<P> > que; fill(d,d+V,INF); que.push(P(0,s)); //初始化 while(!que.empty()){ P p= que.top(); que.pop(); int v=p.second; //取出编号 if(d[v]<p.first) continue; //检查与d是否是最小的,确定是否更新d for(int i=0;i<G[v].size();i++){ //更新v的连接边 edge e=G[v][i]; if(d[e.to]<d[v]+e.cost){ d[e.to]=d[v]+e.cost; que.push(P(d[e.to],e.to)); //将更新后的最小边加入que } } } } int main(){ dijkstra1(0); dijkstra2(0); return 0; }