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