acm 模板

ACM模板



并查集--------------------------------------------------------------------------------------( 2 )

母函数--------------------------------------------------------------------------------------( 3 )

几何模板-----------------------------------------------------------------------------------( 3 )

二分匹配-----------------------------------------------------------------------------------( 6 )

最短路径-----------------------------------------------------------------------------------( 7 )

多重背包二进制模板(01背包)----------------------------------------------------( 8 )

qsort排序---------------------------------------------------------------------------------( 9 )

C++ sort排序-----------------------------------------------------------------------------( 11 )

三分查找-----------------------------------------------------------------------------------( 12 )

搜索-----------------------------------------------------------------------------------------( 12 )

string---------------------------------------------------------------------------------------( 15 )

map-----------------------------------------------------------------------------------------( 16 )

几何公式-----------------------------------------------------------------------------------( 16 )

组合公式-----------------------------------------------------------------------------------( 19 )

筛选法(素数)--------------------------------------------------------------------------( 19 )

最大连续子序列--------------------------------------------------------------------------( 20 )

set------------------------------------------------------------------------------------------( 20 )





























并查集(HDU 1233)

#include<iostream>

#include<algorithm>

using namespace std;

int sum,h[55000],root[55000];

struct sj

{

int a,b,len;

}q[55000];

bool cmp(sj a,sj b)

{

return a.len<b.len;

}

int find(int x)

{

while(x!=root[x])

x=root[x];

return x;

}

void hebin(int x,int y,int k)

{

sum+=k;

if(h[x]>h[y])

root[y]=x;

else

{

if(h[x]<h[y])

root[x]=y;

else

root[y]=x,h[x]++;

}

}

main()

{

int m,n,i,fx,fy;

while(cin>>n&&n)

{

sum=0;

m=(n*(n-1))/2;

for(i=1;i<=m;i++)

{

cin>>q[i].a>>q[i].b>>q[i].len;

h[i]=1,root[i]=i;

}

sort(q+1,q+m+1,cmp);

for(i=1;i<=m;i++)

{

fx=find(q[i].a),fy=find(q[i].b);

if(fx!=fy)

hebin(fx,fy,q[i].len);

}

cout<<sum<<endl;

}

}

母函数(1028)

#include <iostream>

using namespace std;

const int lmax=300;

int c1[lmax+1],c2[lmax+1];

main()

{

int n,i,j,k;

while(cin>>n&&n!=0)

{

for(i=0;i<=n;i++)

c1[i]=1,c2[i]=0;

for(i=2;i<=n;i++)

{

for(j=0;j<=n;j++)

for (k=0;k+j<=n;k+=i)

c2[j+k]+=c1[j];

for (j=0;j<=n;j++)

c1[j]=c2[j],c2[j]=0;

}

cout<<c1[n]<<endl;

}

}

几何模板(1086)

#include<stdio.h>

#define max(a,b) a>b?a:b

#define min(a,b) a>b?b:a



struct Point

{

double x,y;

};

struct line

{

Point s;

Point e;

};

line node[110];

double dir(Point p0,Point p1,Point p2)

{

return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));

}

bool on(Point pi, Point pj ,Point pk)

{

if(((min(pi.x,pj.x)<=pk.x)&&(max(pi.x,pj.x)>=pk.x))&&((min(pi.y,pj.y)<=pk.y)&&(max(pi.y,pj.x)>=pk.y)))

return true ;

else return false;

}

bool ATM(Point p1,Point p2,Point p3,Point p4)

{

double d1,d2,d3,d4;

d1=dir(p3,p4,p1);

d2=dir(p3,p4,p2);

d3=dir(p1,p2,p3);

d4=dir(p1,p2,p4);

if(d1*d2<0&&d3*d4<0) return true;

else if(d1==0&&on(p3,p4,p1)) return true;

else if(d2==0&&on(p3,p4,p2)) return true;

else if(d3==0&&on(p1,p2,p3)) return true;

else if(d4==0&&on(p1,p2,p3)) return true;

else return false;

}

main()

{

int sum,t,i,j;

while(scanf("%d",&t)==1&&t)

{

for(i=1;i<=t;i++)

scanf("%lf%lf%lf%lf",&node[i].s.x,&node[i].s.y,&node[i].e.x,&node[i].e.y);



sum=0;



for(i=1;i<=t;i++)

for(j=i+1;j<=t;j++)

{

if(ATM(node[i].s,node[i].e,node[j].s,node[j].e))

sum++;

}

printf("%d\n",sum);

}

return 0;

}














二分匹配(1083)

#include<iostream>

using namespace std;

#include<stdio.h>

#include<vector>

vector<int>map[1005];

int link[1005];

int flag[1005];

int num,n,p;

int find(int i)

{

int j;

for(j=0;j<map[i].size();j++)

{

if(flag[map[i][j]]==0)

{

flag[map[i][j]]=1;

if(link[map[i][j]]==-1||find(link[map[i][j]]))

{

link[map[i][j]]=i;

return 1;

}

}

}

return 0;

}

int main(void)

{

int a,b,z,i,j,t;

while(cin>>t)

{

while(t--)

{

cin>>n>>p;

for(i=1;i<=n;i++)

{

map[i].clear();

}

for(i=1;i<=n;i++)

{

cin>>b;

while(b--)

{

cin>>a;

map[i].push_back(a);

}

}

num=0;

memset(link,-1,sizeof(link));

for(i=1;i<=n;i++)

{

memset(flag,0,sizeof(flag));

if(find(i))

num++;

}

if(num==n) cout<<"YES"<<endl;

else cout<<"NO"<<endl;

}

}

return 0;

}



最短路径(2544)

#include<iostream>

using namespace std;

int map[110][110], d[110], flag[110];

#define max 10000000;

main()

{

int n,m,a,b,c,i,j,v;

int min;

while(cin>>n>>m)

{

if(n==0&&m==0) return 0;

memset(flag,0,sizeof(flag));



for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

map[i][j]=max;



for(i=1;i<=m;i++)

{

cin>>a>>b>>c;

If(map[a][b]<c)

{

map[a][b]=c;

map[b][a]=c;

flag[a]=flag[b]=1;

}

}

for(i=1;i<=n;i++)

d[i]=map[1][i];



for(i=1;i<n;i++)

{

min=max;

for(j=1;j<=n;j++)

{

if(flag[j]==1&&min>d[j])

{

v=j;

min=d[j];

}

}

flag[v]=0;

for(j=1;j<=n;j++)

{

if(flag[j]==1&&d[j]>d[v]+map[v][j])

d[j]=d[v]+map[v][j];

}

}

cout<<d[n]<<endl;

}

}

多重背包二进制模板(1059)

#include<iostream>

using namespace std;

#include<stdio.h>

bool dp[1<<20];

int num[10];

int main(void)

{

int m,n,i,j,t,left,k,count,sum,kk=1;

while(cin>>num[1]>>num[2]>>num[3]>>num[4]>>num[5]>>num[6])

{

if(num[1]+num[2]+num[3]+num[4]+num[5]+num[6]==0) return 0;

sum=0;

for(i=1;i<=6;i++)

sum+=num[i]*i;

if(sum%2==1)

{printf("Collection #%d:\nCan't be divided.\n\n",kk++);continue;}

for(i=1;i<=sum;i++)

dp[i]=false;

dp[0]=true;

for(i=1;i<=6;i++)

{

left=num[i];

for(k=1;k<=left;k<<=1)

{

t=k*i;

for(j=sum/2;j>=t;j--)

{

if(dp[j-t])

dp[j]=true;

}

left-=k;

}

if(left)

{

t=left*i;

for(j=sum/2;j>=t;j--)

{

if(dp[j-t])

dp[j]=true;

}

}

}

printf("Collection #%d:\n",kk++);

if(dp[sum/2]) printf("Can be divided.\n");

else printf("Can't be divided.\n");

cout<<endl;

}

}

01背包

for i=1..N
for v=V..0
f[v]=max{f[v],f[v-c[i]]+w[i]};
qsort排序

#include<stdilib.h>



一、对int类型数组排序

int num[100];

Sample:

int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}

qsort(num,100,sizeof(num[0]),cmp);

二、对char类型数组排序(同int类型)

char word[100];

Sample:

int cmp( const void *a , const void *b )
{
return *(char *)a - *(char *)b;
}

qsort(word,100,sizeof(word[0]),cmp);

三、对double类型数组排序(特别要注意)

double in[100];

int cmp( const void *a , const void *b )
{
return *(double *)a > *(double *)b ? 1 : -1;
}

qsort(in,100,sizeof(in[0]),cmp);

四、对结构体一级排序

struct In
{
double data;
int other;
}s[100]

//按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种,参考上面的例子写

int cmp( const void *a ,const void *b)
{
return (*(In *)a).data > (*(In *)b).data ? 1 : -1;
}

qsort(s,100,sizeof(s[0]),cmp);

五、对结构体二级排序

struct In
{
int x;
int y;
}s[100];

//按照x从小到大排序,当x相等时按照y从大到小排序

int cmp( const void *a , const void *b )
{
struct In *c = (In *)a;
struct In *d = (In *)b;
if(c->x != d->x) return c->x - d->x;
else return d->y - c->y;
}

qsort(s,100,sizeof(s[0]),cmp);

六、对字符串进行排序

struct In
{
int data;
char str[100];
}s[100];

//按照结构体中字符串str的字典顺序排序

int cmp ( const void *a , const void *b )
{
return strcmp( (*(In *)a)->str , (*(In *)b)->str );
}

qsort(s,100,sizeof(s[0]),cmp);

七、计算几何中求凸包的cmp

int cmp(const void *a,const void *b) //重点cmp函数,把除了1点外的所有点,旋转角度排序
{
struct point *c=(point *)a;
struct point *d=(point *)b;
if( calc(*c,*d,p[1]) < 0) return 1;
elseif(!calc(*c,*d,p[1])&&dis(c->x,c->y,p[1].x,p[1].y)<dis(d->x,d->y,p[1].x,p[1].y)) //如果在一条直线上,则把远的放在前面
return 1;
else return -1;
}

sort

Sort排序

头文件

#include<iostream>

using namespace std;

#include<algotihm>

对数组int a[100]进行排序

bool cmp (int a,int b)

{ return a>b} 从大到小 反之则是从小到大

int main(void)

{

sort(a,a+n,cmp);数组的起始位置,数组的末尾位置,排序函数;

}

三分查找









搜索(1010)

1.使用queue

#include<iostream>

using namespace std;

#include<queue>

#include<stdio.h>

int mapt[60][60][60];

int flag[60][60][60];

int dir[6][3]={{0,0,1},{0,0,-1},{0,-1,0},{0,1,0},{1,0,0},{-1,0,0}};

struct ss

{

int x,y,z,time;

};

int A,B,C,T;

void dfs()

{

int i,j,k;

flag[1][1][1]=1;

ss temp,p;

queue<ss>q;

p.x=p.y=p.z=1;

p.time=0;

q.push(p);

while(!q.empty())

{

p=q.front();

q.pop();

for(i=0;i<6;i++)

{

temp=p;

temp.x+=dir[i][0];

temp.y+=dir[i][1];

temp.z+=dir[i][2];

temp.time=p.time+1;

if(temp.x<1||temp.x>A||temp.y<1||temp.y>B||temp.z<1||temp.z>C||mapt[temp.x][temp.y][temp.z]==1)

continue;

if(temp.x==A&&temp.y==B&&temp.z==C)

{

if(T>=temp.time)

{

cout<<temp.time<<endl;

}

else

cout<<"-1"<<endl;

return ;

}

if(flag[temp.x][temp.y][temp.z]==0&&mapt[temp.x][temp.y][temp.z]==0)

{

q.push(temp);

flag[temp.x][temp.y][temp.z]++;

}

}

}

cout<<"-1"<<endl;

}



int main(void)

{

int ww,t,i,j,k;

cin>>t;

while(t--)

{

cin>>A>>B>>C>>T;

memset(flag,0,sizeof(flag));

ww=0;

for(i=1;i<=A;i++)

for(j=1;j<=B;j++)

for(k=1;k<=C;k++)

{

scanf("%d",&mapt[i][j][k]);

if(!mapt[i][j][k]) ww++;

}

if(A+B+C+1>ww)

cout<<"-1"<<endl;

else

dfs();

}

return 0;

}

2.不使用queue

# include <iostream.h>

# include <string.h>

# include <stdlib.h>

char map[9][9];

int n,m,t,di,dj;

bool escape;

int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};

void dfs(int si,int sj,int cnt)

{ int i,temp;

if(si>n||sj>m||si<=0||sj<=0) return;

if(cnt==t&&si==di&&sj==dj) escape=1;

if(escape) return;



temp=(t-cnt)-abs(si-di)-abs(sj-dj);

if(temp<0||temp&1) return;

for(i=0;i<4;i++){

if(map[si+dir[i][0]][sj+dir[i][1]]!='X')

{

map[si+dir[i][0]][sj+dir[i][1]]='X';

dfs(si+dir[i][0],sj+dir[i][1],cnt+1);

map[si+dir[i][0]][sj+dir[i][1]]='.';

}

}

return;

}

int main()

{

int i,j,si,sj;

while(cin>>n>>m>>t)

{

if(n==0&&m==0&&t==0) break;

int wall=0;

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

{

cin>>map[i][j];

if(map[i][j]=='S') { si=i; sj=j; }

else if(map[i][j]=='D') { di=i; dj=j; }

else if(map[i][j]=='X') wall++;

}

if(n*m-wall<=t)

{

cout<<"NO"<<endl;

continue;

}

escape=0;

map[si][sj]='X';

dfs(si,sj,0);

if(escape) cout<<"YES"<<endl;

else cout<<"NO"<<endl;

}

}

string



数组赋值

memset(s,0,sizeof(s)) 其中s为定义了的数组名

返回字符串长度

strlen(s);

字符串比较函数

strcmp(a,b) 若相同则返回0;

数组拷贝函数

strcpy(a,b) b拷贝至a

Map

#include<iostream>

using namespace std;

#include<map>

#include<string>

int main(void)

{

map<string,int>aa;

map<string,int>::iterator it;

string c;

int t,i;

aa.clear();

cin>>t;

while(t--)

{

cin>>c;

aa[c]++;

}

if(aa.find(2)!=aa.end())

{

cout<<aa[2];

}

for(it=aa.begin();it!=aa.end();it++)

{

cout<<it->first<<" "<<it->second<<endl;

}

}

几何公式

三角形:

1. 半周长P=(a+b+c)/2

2. 面积S=aHa/2=absin(C)/2=sqrt(P(P-a)(P-b)(P-c))

3. 中线Ma=sqrt(2(b^2+c^2)-a^2)/2=sqrt(b^2+c^2+2bccos(A))/2

4. 角平分线Ta=sqrt(bc((b+c)^2-a^2))/(b+c)=2bccos(A/2)/(b+c)

5. 高线Ha=bsin(C)=csin(B)=sqrt(b^2-((a^2+b^2-c^2)/(2a))^2)

6. 内切圆半径r=S/P=asin(B/2)sin(C/2)/sin((B+C)/2)

=4Rsin(A/2)sin(B/2)sin(C/2)=sqrt((P-a)(P-b)(P-c)/P)

=Ptan(A/2)tan(B/2)tan(C/2)

7. 外接圆半径R=abc/(4S)=a/(2sin(A))=b/(2sin(B))=c/(2sin(C))

四边形:

D1,D2 为对角线,M 对角线中点连线,A 为对角线夹角

1. a^2+b^2+c^2+d^2=D1^2+D2^2+4M^2

2. S=D1D2sin(A)/2

(以下对圆的内接四边形)

3. ac+bd=D1D2

4. S=sqrt((P-a)(P-b)(P-c)(P-d)),P 为半周长

正n 边形:

R 为外接圆半径,r 为内切圆半径

1. 中心角A=2PI/n

2. 内角C=(n-2)PI/n

3. 边长a=2sqrt(R^2-r^2)=2Rsin(A/2)=2rtan(A/2)

4. 面积S=nar/2=nr^2tan(A/2)=nR^2sin(A)/2=na^2/(4tan(A/2))

圆:

1. 弧长l=rA

2. 弦长a=2sqrt(2hr-h^2)=2rsin(A/2)

3. 弓形高h=r-sqrt(r^2-a^2/4)=r(1-cos(A/2))=atan(A/4)/2

4. 扇形面积S1=rl/2=r^2A/2

5. 弓形面积S2=(rl-a(r-h))/2=r^2(A-sin(A))/2

棱柱:

1. 体积V=Ah,A 为底面积,h 为高

2. 侧面积S=lp,l 为棱长,p 为直截面周长

3. 全面积T=S+2A

棱锥:

1. 体积V=Ah/3,A 为底面积,h 为高

(以下对正棱锥)

2. 侧面积S=lp/2,l 为斜高,p 为底面周长

3. 全面积T=S+A

棱台:

1. 体积V=(A1+A2+sqrt(A1A2))h/3,A1.A2 为上下底面积,h 为高

(以下为正棱台)

2. 侧面积S=(p1+p2)l/2,p1.p2 为上下底面周长,l 为斜高

3. 全面积T=S+A1+A2

圆柱:

7

1. 侧面积S=2PIrh

2. 全面积T=2PIr(h+r)

3. 体积V=PIr^2h

圆锥:

1. 母线l=sqrt(h^2+r^2)

2. 侧面积S=PIrl

3. 全面积T=PIr(l+r)

4. 体积V=PIr^2h/3

圆台:

1. 母线l=sqrt(h^2+(r1-r2)^2)

2. 侧面积S=PI(r1+r2)l

3. 全面积T=PIr1(l+r1)+PIr2(l+r2)

4. 体积V=PI(r1^2+r2^2+r1r2)h/3

球:

1. 全面积T=4PIr^2

2. 体积V=4PIr^3/3

球台:

1. 侧面积S=2PIrh

2. 全面积T=PI(2rh+r1^2+r2^2)

3. 体积V=PIh(3(r1^2+r2^2)+h^2)/6

球扇形:

1. 全面积T=PIr(2h+r0),h 为球冠高,r0 为球冠底面半径

2. 体积V=2PIr^2h/3

组合公式

1. C(m,n)=C(m,m-n)

2. C(m,n)=C(m-1,n)+C(m-1,n-1)

derangement D(n) = n!(1 - 1/1! + 1/2! - 1/3! + ... + (-1)^n/n!)

= (n-1)(D(n-2) - D(n-1))

Q(n) = D(n) + D(n-1)

求和公式,k = 1..n

1. sum( k ) = n(n+1)/2

2. sum( 2k-1 ) = n^2

3. sum( k^2 ) = n(n+1)(2n+1)/6

4. sum( (2k-1)^2 ) = n(4n^2-1)/3

5. sum( k^3 ) = (n(n+1)/2)^2

6. sum( (2k-1)^3 ) = n^2(2n^2-1)

7. sum( k^4 ) = n(n+1)(2n+1)(3n^2+3n-1)/30

8. sum( k^5 ) = n^2(n+1)^2(2n^2+2n-1)/12

9. sum( k(k+1) ) = n(n+1)(n+2)/3

10. sum( k(k+1)(k+2) ) = n(n+1)(n+2)(n+3)/4

12. sum( k(k+1)(k+2)(k+3) ) = n(n+1)(n+2)(n+3)(n+4)/5



筛选法(素数)

for(i=2;i*i<=n;i++)

if(p[i]==0)

for(j=i*i;j<=n;j+=i)

p[j]=1;



最大连续子序列(1231)

#include<stdio.h>

int sta,ed,n,j,sum,maxsum,ut[100001],b;

main()

{

while(scanf("%d",&n),n)

{

sum=0;maxsum=-999;

for(b=j=1;j<=n;j++)

{

scanf("%d",&in1[j]);

sum+=ut[j];

if(sum>maxsum)

{

maxsum=sum;

ed=j;

sta=b;

}

if(sum<0)

{

sum=0;

b=j+1;

}

}

if(maxsum<0)

printf("0 %d %d\n",ut[1],ut[n]);

else

printf("%d %d %d\n",maxsum,ut[sta],ut[ed]);

}

}

set

#include<iostream>

using namespace std;

#include<string>

#include<set>

int main(void)

{

set<string>ac;

set<string>wa;

set<string>::iterator it;

int tt,t,n;

string a,b;

cin>>t;

while(t--)

{

cin>>n;

ac.clear();

wa.clear();

while(n--)

{

cin>>tt>>a>>b;

if(tt>=0&&tt<=300)

{

if(b=="Accept")

{

if(wa.find(a)!=wa.end())

wa.erase(a);

ac.insert(a);

}

else

{

if(ac.find(a)==ac.end())

wa.insert(a);

}

}

cout<<"Accept: ";

for(it=ac.begin();it!=ac.end();it++)

cout<<*it;

cout<<endl;

cout<<"Wrong: ";

for(it=wa.begin();it!=wa.end();it++)

cout<<*it;

cout<<endl;

cout<<endl;

}

}

return 0;

}


你可能感兴趣的:(acm 模板)