NOIP算法分类总结C语言Word格式.docx

上传人:b****6 文档编号:20699417 上传时间:2023-01-25 格式:DOCX 页数:18 大小:19.05KB
下载 相关 举报
NOIP算法分类总结C语言Word格式.docx_第1页
第1页 / 共18页
NOIP算法分类总结C语言Word格式.docx_第2页
第2页 / 共18页
NOIP算法分类总结C语言Word格式.docx_第3页
第3页 / 共18页
NOIP算法分类总结C语言Word格式.docx_第4页
第4页 / 共18页
NOIP算法分类总结C语言Word格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

NOIP算法分类总结C语言Word格式.docx

《NOIP算法分类总结C语言Word格式.docx》由会员分享,可在线阅读,更多相关《NOIP算法分类总结C语言Word格式.docx(18页珍藏版)》请在冰豆网上搜索。

NOIP算法分类总结C语言Word格式.docx

If(p%2==0||p%3==0)returnfalse;

For(inti=5;

i<

=x;

i+=2)

If(p%i==0)returnfalse;

Returntrue;

4.暴力分解质因数

Intrecord[10000];

VoidBaoli(longp){

Longx=sqrt(p)+1,i,lc=0,ok=true;

If(prime(p)==1){

Lc=1;

record[lc]=p;

Return;

}

for(i=2;

(i<

=x)&

&

ok;

i++){

While(p%i==0){

lc++;

Record[lc]=i;

P/=i;

If(p==1){

ok=false;

Break;

}

5.卡特兰数

longf[1001]={0};

longCountCatalan(longn){

f[0]=f[1]=1;

for(longi=1;

=n;

f[i]=0;

for(longj=1;

j<

=i;

j++)

f[i]+=f[i-j]*f[j-1];

returnf[n];

Part2.排序相关

1.快排

VoidQuickSort(int*A,intp1,intp2){

If(p1>

=p2)return;

Intx=A[(p1+p2)>

>

1],i=p1,j=p2;

While(i<

j){

while(A[i]<

x)i++;

While(A[j]>

x)j--;

If(i<

=j){

IntTemp=A[i];

A[i]=A[j];

A[j]=Temp;

i++;

j--;

QuickSort(A,p1,j);

QuickSort(A,i,p2);

2.冒泡排序

VoidBubbleSort(int*A,intn){

Inttemp;

For(inti=1;

n;

i++)

For(intj=i;

If(a[j-1]>

a[j])

temp=a[j-1],a[j-1]=a[j],a[j]=temp;

3.堆排序

VoidMinHeapify(intp,constintHeapSize){

IntSmall=p;

If(p*2<

=HeapSize&

a[p*2]<

a[Small])

Small=p*2;

If(p*2+1<

=Heapsize&

a[p*2+1]<

Small=p*2+1;

If(Small!

=p){

Inttemp=a[p];

a[p]=a[small];

a[small]=temp;

MinHeapify(small,HeapSize);

voidExtraMin(int&

HeapSize){

Intans=a[1];

a[1]=a[HeapSize];

A[HeapSize--]=ans;

MinHeapify

(1);

VoidHeapsort(intn){

HeapSize=n;

For(inti=n/2;

i>

=1;

i--)

MinHeapify(i,HeapSize);

ExtraMin(HeapSize);

Part3.图论相关

1.最小生成树prim算法

Constintmaxint=(1<

<

16)-1;

Intg[][],dis[],n,visit[];

intPrim(){

intmst=0;

Intdex=1,temp=-1;

For(inti=1;

i++)dis[i]=maxint;

Dis[dex]=0;

=n-1;

Visit[dex]=1;

For(intj=1;

j++){

If(visit[j]==0){

If(g[dex][j]!

=0&

g[dex][j]<

dis[j])dis[j]=g[dex][j];

If(temp==-1||dis[j]<

dis[temp])temp=j;

}

dex=temp;

mst+=dis[dex];

Returnmst;

}//O(n^2)

2.最小生成树prim算法利用最小堆优化且图用邻接表存储

constlongmaxint=(1<

30-1);

structHnode{

longdis,v;

Hnode(){

v=0;

dis=maxint;

};

structGnode{

longv,w,pos,In;

structGnode*next;

Gnode(){

next=NULL;

v=w=In=pos=0;

}G[2001];

longn,m,vis[2001]={0};

longx,y,z;

classHeapClass{

public:

HnodeA[2001];

longSize;

voidMinHeapify(longdep){

longSmall=dep;

structHnodeTemp;

if(2*dep<

=Size&

A[Small].dis>

A[2*dep].dis)

Small=2*dep;

if(2*dep+1<

A[2*dep+1].dis)

Small=2*dep+1;

if(Small!

=dep){

Temp=A[Small];

A[Small]=A[dep];

A[dep]=Temp;

G[A[dep].v].pos=dep;

G[A[Small].v].pos=Small;

MinHeapify(Small);

structHnodeExtraMin(){

structHnodeAns=A[1];

A[1]=A[Size--];

G[A[Size+1].v].pos=Size+1;

G[A[1].v].pos=1;

MinHeapify

(1);

returnAns;

voidDecrease(longdep){

Hnodex=A[dep];

longi;

while(dep>

1){

i=dep/2;

if(A[i].dis<

=x.dis)break;

A[dep]=A[i],G[A[dep].v].pos=dep;

dep=i;

A[dep]=x;

G[A[dep].v].pos=dep;

}Heap;

longPrim(){

longMST=0;

Heap.A[1].v=1;

Heap.A[1].dis=0;

G[1].pos=1;

for(inti=2;

Heap.A[i].v=i;

G[i].pos=i;

for(i=n/2;

Heap.MinHeapify(i);

for(intk=1;

k<

k++){

HnodeNow=Heap.ExtraMin();

MST+=Now.dis;

G[Now.v].pos=-1;

Gnode*T=G[Now.v].next;

while(T){

if((G[T->

v].pos!

=-1)&

((T->

w)<

(Heap.A[G[T->

v].pos].dis))){

Heap.A[G[T->

v].pos].dis=T->

w;

Heap.Decrease(G[T->

v].pos);

T=T->

next;

RetrunMST;

}//O(nlogn)

3.最小生成树kruskal算法利用并查集(的路径压缩)优化

intf[],m,n;

//m表示边数,n表示节点数

StructEdge{

Intx,y,w;

}E[100000],Temp,P;

Intfind(intx){

If(f[x]!

=x)

f[x]=find(f[x]);

Returnf[x];

}//并查集的性价比多高啊。

就几行代码。

VoidQsort(intp1,intp2){

If(p1>

P=E[rand()%(p2-p1)+p1];

Inti=p1,j=p2;

While(i<

while(E[i].w<

P.w)i++;

While(E[j].w>

P.w)j--;

If(i<

Temp=E[i],E[i]=E[j],E[j]=Temp;

i++,j--;

Qsort(p1,j),Qsort(i,p2);

IntKruskal(){

Intmst=0,cnt=0;

//cnt用于记录已经加入了多少条边

f[i]=i;

Qsort(1,m);

=m;

Intfx=find(E[i].x),fy=find(E[i].y);

If(fx!

=fy){

f[fx]=fy;

//并查集的合并操作。

mst+=E[i].w;

cnt++;

If(cnt==n-1)break;

}//O(ElogE)

4.求各点间最短距离的floyd算法

VoidFloyd(){

For(intk=1;

k++)

For(inti=1;

For(intj=1;

If(g[i][k]>

0&

g[k][j]>

g[i][k]+g[k][j]<

g[i][j])

g[i][j]=g[i][k]+g[k][j];

5.单源最短路的dijstra算法(写出来跟prim的样子差不多)

Intvisit[]={0},dis[],g[][]

VoidDijstra(){

dis[dex]=0;

for(inti=1;

if(visit[j]==0){

If(dis[dex]+g[dex][j]<

dis[j])dis[j]=dis[dex]+g[dex][j];

}//O(n^2)..跟prim差不多一模一样。

//加个堆呢?

也是跟prim差不多。

自己写吧。

6.单源最短路的SPFA算法(用队列优化的bellman-ford算法)

IntInqueue[]={0},Queue[],head=0,tail=1;

Intdis[],g[][],dex;

VoidSPFA(){

Inqueue[1]=1,Queue[1]=1;

Do{

head++;

Inqueue[Queue[head]]=0;

dex=Queue[head];

If(g[dex][i]>

g[dex][i]+dis[dex]<

dis[i]){

dis[i]=g[dex][i]+dis[dex];

If(Inqueue[i]==0){

Inqueue[i]=1;

Queue[++tail]=i;

}

}while(head<

tail);

}//理想状态下是O(E);

7.BFS框架

intg[][],Q[],visit[];

intbegin=0,end=0;

voidBFS(){

Q[end++]=1;

visit[1]=true;

while(begin<

end){

intx=Q[begin++];

for(inti=1;

if(g[x][i]&

!

visited[i]){

Q[end++]=i;

visit[i]=true;

8.DFS框架

Intg[][],visit[];

Voiddfs(intdep){

if(visit[dep]==1)return;

Visit[dep]=1;

If(g[dep][i])

dfs(i);

Part4.数据结构

1.BinarySearchTree(二叉搜索树)=BST

structTnode{

intkey;

structTnode*left,*right,*p;

structBST{

structTnode*Root;

BST(){

Root=new(Tnode);

Root=NULL;

voidInsert(intkey){

structTnode*New=new(Tnode);

New->

key=key;

left=New->

right=New->

p=NULL;

structTnode*F=NULL,*T=Root;

F=T;

if((T->

key)>

key)T=T->

left;

elseT=T->

right;

p=F;

if(!

F)Root=New;

elseif((F->

key)F->

left=New;

elseF->

right=New;

structTnode*Search(intkey){

structTnode*T=Root;

key)==key)returnT;

structTnode*Min(structTnode*T){

structTnode*F=NULL;

returnF;

voidDelete(intkey){

structTnode*T=Search(key);

//NOSON;

T->

left&

right){

if(T->

p->

left==T)T->

left=NULL;

elseT->

right=NULL;

delete(T);

return;

//OnlyLeftSon;

if(T->

left=T->

right=T->

T->

left->

p=T->

p;

//OnlyRightSon;

right->

//BothLeftSonandRightSon;

structTnode*M=Min(T->

right);

//FindM,T<

M<

(T->

if(M->

left==M)M->

//RemoveEdgebetweenMandM->

elseM->

M->

M->

//CopyMtoT;

left==T)M->

left=M;

right=M;

p=M;

voidWalk(structTnode*T){

T)return;

Walk(T->

left);

cout<

key<

"

"

;

2.IntervalTree(线段树or区间树)

intl,r,m,sum;

Tnode(){

l=r=m=sum=0;

left=right=p=NULL;

structIntervalTree{

Tnode*Root;

//初始化

voidInit(intn){

Root->

l=1;

Root->

r=n;

m=(n>

1);

left=Root->

right=Root->

Build(Root);

//从根开始,建立链接结构

//建立链接结构的过程

voidBuild(Tnode*T){

if((T->

l)==(T->

r)){

T->

sum=A[T->

l];

return;

Tnode*L=new(Tnode),*R=new(Tnode);

left=L;

right=R;

L->

p=R->

p=T;

l=T->

l;

L->

r=T->

m;

m=(L->

l+L->

r)>

1;

R->

m+1;

R->

r;

m=(R->

l+R->

Build(L);

Build(R);

sum=L->

sum+R->

sum;

//后序遍历

voidWalk(Tnode*T){

if(!

Walk(T->

cout<

l)<

r)<

sum)<

endl;

//更新在p上的节点的值;

voidUpdate(intp,intx){

Tnode*T=Root;

while(T){

if((T->

r)&

l)==p)break;

m)<

p)T=T->

elseT=T->

T->

sum=x;

//更新该节点上面所有节点sum值;

T=T->

sum=(T->

sum+T->

sum);

//查询某区间关键字之和;

intAsk(Tnode*T,intl,intr){

l)==l&

r)==r)returnT->

r))returnT->

if(r<

=(T->

m))

returnAsk(T->

left,l,r);

elseif(l>

returnAsk(T->

right,l,r);

elsereturnAsk(T->

left,l,T->

m)+Ask(T->

right,T->

m+1,r);

3.Treap=BSTree+Heap

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 日语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1