系统性训练,励志刷完挑战程序设计竞赛-代码整理103~134【初级篇】

来源:互联网 发布:市场调查数据 编辑:程序博客网 时间:2024/06/16 15:43

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类型,名称叫aint* a 声明一个int指针类型,名称叫aint& 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%mx=x*x%m;n>>=1;   //n/2 }return res;}/*大整数取模n mod m1234=(((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;} 


2 0
原创粉丝点击