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;

}

 

 

ACM 模板_第1张图片

 

 

 

 

二分匹配(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);数组的起始位置,数组的末尾位置,排序函数;

}

三分查找

 

ACM 模板_第2张图片

 

 

搜索(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 模板)