ACM资料整理

来源:互联网 发布:红外成像目标跟踪算法 编辑:程序博客网 时间:2024/06/09 20:22

一、做题时应注意的地方

1、

做题时考虑输出结果的上、下边际范围,极限值,尤其是在做简单题的时候。

2、

除法能换成乘法的地方,尽量用乘法。

3、

做题时,确保每个句子、每个单词都读懂,读题是做题的根本

4、

处理字符串,千万要保证它以“\0”结尾

5、

进行数组优化,可以在输入的时候就进行向结果靠拢的操作

6、

应用分治处理时

调用函数时,传数组只需打入数组名

传数组内元素如:temp(a[0]);

7、

C语言中大多数头文件在C++中仍然可以用,但推荐在头文件前加一个小写的c字母,然后去掉.h后缀,如ctype.h——cctype

8、

比赛结束前,一定要把正确率稍高点的题都看完

9、

做题时,弄懂题意是前提,普遍最先刷出来的题一定是水题,普遍都做出来的题也一定不难,不要把问题复杂化

10、

注意题目中,测试数据的范围,数组千万别开小了,数据的类型千万别选错了

11、

分治三步法

划分问题:把问题的实例划分成子问题

递归求解:递归解决子题

合并问题:合并子问题的解得到原问题的解

12、

有的题可能用到

scanf("%d,%d",&a,&b);

scanf("%d/%d",&a,&b);

中间必须要输入该字符才可以

13、

浮点数计算有误差,可以用a- dis > 1e-5的形式,

14、

有时题意有说输入时,N>M,但还是比较交换一下确保比较好

15、

对数是处理数论的主要工具

二、零散知识点补漏

1、

^为位运算,表示异或,开关性

   如:1010^1111=0101

与(&)、或(|)、非(!)

 

与集合有关的题可以用位运算:

10110:表示集合{1,2,4}

01100:表示集合{2,3}

位的最后一位为1,表示空集。

全集定义为ALL_BITS=(1<<n)-1

与、或、非,对应集合的交、并、对称差

2、

数组开的很大时,放在main()函数外面

3、

a[x][y]==0;可简写为!a[x][y];

4、

可用如下语句控制空格的输出,第一个输出前没有空格,剩下的输出前都以空格。

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

       {

           if (i != 0) printf(" ");

           ………………..     

       }

5、

C++输入带空格的字符串(特别注意,字符串必须用string类型)

   举例: #include<iostream>

using namespace std;

int main()

{

    string s;

   while(getline(cin,s)!=NULL)

        {

               cout<<s<<endl;

    }

               return 0;

}

6、

在C语言中,“乘以2”也可以写成“<<1”,意思是“左移一位”。

7、

0、1互换,可应用于标记法

#include<iostream>

usingnamespace std;

int main()

{

    int a,q=1;

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

    {

        q=!q;

        cout<<q<<" ";

    }

    return 0;

}

输出结果:0 1 0 1

重点:q=!q;

8、

PI=acos(-1.0)

9、

C语言中“%03d”:输出一个数值变量,不足3位前面补0.

10、

不借助变量交换(不推荐用)

   int a,b;

   scanf("%d%d",&a,&b);

   a=a+b;

   b=a-b;

   a=a-b;

printf("%d%d\n",a,b);

可简化为a^=b^=a^=b;

11、

C语言中输出“%d”字符

用printf("%%d");

puts("%d");

12、

竞赛平台

int范围约为:-2.1*10^9~2.1*10^9

long long范围约为:-9.2*10^18~9.2*10^18

unsigned long long 范围,0~1.8*10^19

注意:定义无符号类型时要加uLL,如:10108uLL;

13、

计算数据类型的范围

    #include<limits>

   cout<<std::numeric_limits<int>::max()<<endl;     //int能表示的最大值

   cout<<std::numeric_limits<int>::min()<<endl;     //int能表示的最小值

14、

10^-6可编写为1e-6

15、

往数组中输入不定量个数的数

   int a[1000],n=0,x;

   while(cin>>x)

   a[n++]=x;

16、

不限次输入字符

while((c=getchar())!=EOF)        //C语言

17、

if(a[i])意思是,如果a[i]==1;

    If(!a[i])意思是,如果a[i]==0;

18、

测量string类型长度变量用length(),如:

    string t;

    inttt=t.length();

19、typedef struct

可用typedef struct{double x,y;}Point;的形式代替结构体,让其更像新生结构类型

20、

string类型的数据相加,就是字符串拼接

21、

定义大数组时尽量用如下形式:

using namespace std;

const int maxn=10000;

int a[maxn];

22、不定长数组:vector

Vercor就是一个不定长数组,例如:若a是一个vector,可以用a.size()读取它的大小,a.resize()改变大小,a.push()_back()向尾部添加元素,a.pop_back()删除最后一个元素,clear()清空,empty()测试是否为空

Vector是一个模板类,用vector<int> a或者vector<double> b来声明一个vector,vector<int>类似于int a[]的整型数组

23、集合:set

set<string>::iterator是迭代器,类似于指针

set迭代器中的元素已从小到大排列好

24、映射:map

就是从键到值得映射,如:

map<string,int> month_name来表示“月份名字到月份编号”的映射,然后用month_name[“July”]=7;来赋值,更多理解详见UVA156

25、数据结构

1.STL的栈在头文件<stack>中,用stack<int> s声明

2.STL的队列在头文件<queue>中,front()取队列首元素,用queue<int> s声明

3.STL的优先队列在<queue>中,优先级高的先出,用priority_queue<int>pq来声明,top()表示优先出队列的元素

5.栈、队列、优先队列都用push()表示入,用pop()表示出。

26、

用优先队列实现一个“个位数大的整数优先级反而小”

用priority_queue<int, vector<int>, cmp >pq的方式定义。下面是cmp的定义:

struct cmp

{

   bool operator() (const int a,const int b) const   //a的优先级比b小时返回true

    {

       return a%10>b%10;

    }

};

27、

“越小的整数优先级越大到的优先队列”可以写成“ priority_queue<int,vector<int>,greater<int> >pq”

注意:最后的“>”不要写在一起,否则会被认为是“>>”运算符

28、计算一个数转换成二进制中1的个数

#include<iostream>

using namespace std;

int quickOne(int n)

{

       int count = 0;

 

       while (n) {

              count++;

              n= n & (n - 1);

       }

 

       return count;

}

int main()

{

   char n;

   while(cin>>n)

   cout<<quickOne(n)<<endl;

   return 0;

}

*29、麻烦样例的输入

在int main()中输入,并把文件放入程序所在文件夹,检测样例对错

要加有文件#include<cstdio>

freopen("a.txt","r",stdin);

30、允许输入空格的字符输入,到数组中

   char c;

   for(int i=1;i<=5;i++)

       {

           for(int j=1;j<=5;j++)

           {

                a[i][j]=getchar();

           }

           getchar();      //注意:还要有一个getchar()用来放回车符

       }

31、多边形的三角剖分公式

即使求:在一个凸多边形中,通过若干条互不相交的对角线,把这个多边形划分成了若干个三角形。任务是键盘上输入凸多边形的边数n,求不同划分的方案数fn)。

a[n+1]      4n-6------- = -------a[n]         n

a[4]=2,a[5]=5,a[6]=14,a[7]=42

32、文本结束符(:p>)

括号内的,在用freopen("a.txt","r",stdin);该语句的时候,在txt文档中可用到

33、求逆序对数

举例:

#include<iostream>

using namespace std;

long long cnt;

int a[500010];

int T[500010];         //必须定义在前面

void merge_sort(int* A,long long x,longlong y)

{

 

       if(y-x>1)

       {

              int m=x+(y-x)/2;              //划分

              int p=x,q=m,i=x;

              merge_sort(A,x,m);       //递归求解

              merge_sort(A,m,y);       //递归求解

              while(p<m||q<y)

              {

                     if(q>=y||(p<m&&A[p]<=A[q]))

                            T[i++]=A[p++];       //从左半数组复制到临时空间,比较后小的赋给虚拟空间

                     else

                     {

                            T[i++]=A[q++];       //从左半数组复制到临时空间,比较后大的赋给虚拟空间

                            cnt+=m-p;       

                     }

              }

              for(i=x;i<y;i++)

                     A[i]=T[i];         //从辅助空间复制回A数组

       }

}

 

int main()

{

       intn;

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

       {

              cnt=0;

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

                     cin>>a[i];

              merge_sort(a,0,n);

              cout<<cnt<<endl;

       }

       return0;

}

34、求不大于正整数x的与x互质的正整数的个数,

例如phi(1)=1,phi(2)=1,phi(3)=2,phi(4)=2,phi(5)=4,phi(6)=2等等。

unsigned euler(unsigned x)

{     //就是公式

       unsignedi, res=x;

       for(i = 2; i < (int)sqrt(x * 1.0) + 1; i++)

       if(x%i==0){

       res= res / i * (i - 1);

       while(x % i == 0) x /= i; // 保证i一定是素数

       }

       if(x > 1) res = res / x * (x - 1);

       returnres;

}

35、

可以通过数学运算,确定某个变量的范围

36、部分背包问题思路

有n个物体,第i个物体的重量为wi,价值为vi。在总重量不超过C的情况下让总价值尽量高。每个物体都可以之取走一部分,价值和重量按比例计算。

思路:应该综合考虑两个因素。贪心的策略是,优先拿“价值除以重量的值”最大的,直到重量和正好为C判断是否是素数

37、判断是否是素数

 

int prime(int a)

{

   int i;

   for(i=2;i<sqrt(a);i++)

        if(a%i==0)

       return 0;

   if(i>sqrt(a))

return 1;

注意:调用时用if(prime(a[i])==1)

38、一个数分解成素数形式

#include<iostream>

using namespace std;

int main()

{

   int n,n2;

   cin>>n;

   n2=n;

   cout<<n<<"=";

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

    {

       for(;n2%i==0;)

       {

           n2=n2/i;

           cout<<i<<"*";

       }

    }

   cout<<"1";

   return 0;

}

39、把结构体,按某一变量标准快速排序

举例:以e为标准,从小到大排序(整个结构体都以e为标准排序好了)

#include<iostream>

#include<algorithm>

using namespace std;

typedef struct{int s,e;}Time;

bool cmp(Time a,Time b)

{

   return a.e<b.e;

}

int main()

{

   Time t[10005];

   for(int i=0;i<5;i++)

       cin>>t[i].s>>t[i].e;

   sort(t,t+5,cmp);

   for(int i=0;i<5;i++)

       cout<<t[i].s<<" ";

   cout<<endl;

   for(int i=0;i<5;i++)

       cout<<t[i].e<<" ";

   return 0;

}

40、

贪心算法,只考虑当前状态,让它成为最优

三、杂类

1、子集生成

1、增量构造法

#include <iostream>

using namespace std;

int a[20];

/*递归输出n以内所有的子集,其中cur为当前下标,初始值0*/

void print_subset(int n,int* a,int cur){

       for(int i=0;i<cur;i++)//每次递归输出当前子集,靠它来最后输出上一层指定的子集

              cout<<a[i]<<' ';

       cout<<endl;//以行分隔

       //找到当前子集首个值,因为按字典顺序输出,所以每次找到最小的元素,cur>0则minElem=a[cur-1]+1,否则为0

       intminElem = cur?a[cur-1]+1:0;

 

       //从子集第一个值开始遍历,先不看下面的print_subset(n,a,cur+1);但看这for循环,

       //可知是将子集第一个值从头往后依次赋值为minElem-n-1.每次第一个值变化后递归设置下一个值(相当于下一层的第一个值)

       for(int i=minElem;i<n;i++){

              a[cur]=i;//当前层子集第一个值

              //cur+1表示当前层值设置完毕,开始递归下一层,和前面步骤一样。

              //到达最后一层结束后return 到上一层,然后i++,a[cur]的值(首元素)改变,又反复递归下一层...

              print_subset(n,a,cur+1);

       }

}

 

int main(){

       intn ;

       while(cin>>n,n){

              print_subset(n,a,0);

       }

}

1、位向量法

#include <iostream>

using namespace std;

bool b[20]={0};//判断当前每一个节点选中状态

/*递归输出n以内所有的子集,其中b表示该节点是否选中,cur为当前下标,初始值0*/

void print_subset(int n,bool* b,int cur){

       //当cur加到n的时候输出该串节点(解答树)的值

       if(cur==n){

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

                     if(b[i])

                            cout<<i<<' ';

              }

              cout<<endl;

              return ;

       }

       b[cur]=true;//该节点设为选中状态

       print_subset(n,b,cur+1);//cur+1递归该状态时的下一层节点,循环该操作

       b[cur]=false;//该节点设为不选中状态

       print_subset(n,b,cur+1);//cur+1递归该状态时的下一层节点,循环该操作

}

 

int main(){

       intn ;

       while(cin>>n,n){

              print_subset(n,b,0);

       }

}

3、二进制法

#include <iostream>

using namespace std;

int n = 4;

void subset()

{

   for(int S = 0; S < (1<<n); S++)

    {

       cout << "S : " << S << " => ";

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

       {

           if(S & (1<<i))

           {

                cout << i << "";

           }

       }

       cout << endl;

    }

}

int main()

{

   subset();

}

 

 

2、树状数组求逆序数

举例:

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include <algorithm>

#include <string.h>

using namespace std;

const int maxn=500005;

int n;

int aa[maxn]; //离散化后的数组

int c[maxn];    //树状数组

struct Node

{

  int v;

  int order;

}in[maxn];

 

int lowbit(int x)

{

   return x&(-x);

}

 

void update(int t,int value)

{

   int i;

   for(i=t;i<=n;i+=lowbit(i))

    {

       c[i]+=value;

    }

}

 

int getsum(int x)

{

   int i;

   int temp=0;

   for(i=x;i>=1;i-=lowbit(i))

    {

       temp+=c[i];

    }

   return temp;

}

 

bool cmp(Node a ,Node b)

{

   return a.v<b.v;

}

 

 

int main()

{

   int i,j;

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

    {

       //离散化

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

       {

           scanf("%d",&in[i].v);

           in[i].order=i;

       }

       sort(in+1,in+n+1,cmp);

       for(i=1;i<=n;i++) aa[in[i].order]=i;

       //树状数组求逆序

       memset(c,0,sizeof(c));

       long long ans=0;

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

       {

           update(aa[i],1);

           ans+=i-getsum(aa[i]);

       }

       cout<<ans<<endl;

    }

   return 0;

}

 

四、cmath头文件内函数

math.h 数学函数库,一些数学计算的公式的具体实现是放在math.h里,具体有:

1 、三角函数

doublesin (double);

doublecos (double);

doubletan (double);

2 、反三角函数

doubleasin (double); //结果介于[-PI/2, PI/2]

doubleacos (double); //结果介于[0, PI]

doubleatan (double);//反正切(主值),结果介于[-PI/2,PI/2]

doubleatan2 (double, double); //反正切(整圆值),结果介于

[-PI/2,PI/2]

3 、双曲三角函数

doublesinh (double);

doublecosh (double);

doubletanh (double);

4 、指数与对数

doubleexp (double);

doublepow (double a, double b);    //a的b次方

doublesqrt (double);

doublelog (double);      //以e为底的对数

double log10 (double);c++                          中自然对数函数:log(N)   以10为底:log10(N)但没有以2为底的函数但是可以用换底公式解决:log2(N)=log10(N)/log10(2)

5 、取整

doubleceil (double);       //取上整

doublefloor (double);      //取下整

6 、绝对值

doublefabs (double);

7 、准化浮点数

double frexp (doublef, int *p); 标准化浮点数, f = x * 2^p, 已知f

求x, p ( x介于[0.5, 1]) double ldexp (doublex, int p); 与

frexp相反, 已知x,p求f

8 、取整与取余

doublemodf (double,double*);将参数的整数部分通过                         指针回传, 返回小数部分

doublefmod(double,double);返回两参数相除的余数

9 、平方根

sqrt

10、计算直角三角形斜边长

用 法:

 double hypot(doublex, double y);

举例1:

#include <stdio.h>

#include <math.h>

int main(void)

{

    double result;

    double x = 3.0;

    double y = 4.0;

    result = hypot(x, y);

    printf("The hypotenuse is: %lf\n",result);

    return 0;

}

11、四舍五入

floor(x+0.5);    //解释:等于1的区间为[0.5,1.5)

五、cstring头文件内函数(C++字符串函数)

1、strchr函数,查找字符串s中首次出现字符c的位置。

strchr函数原型:extern char *strchr(const char *s,char c);查找字符串s中首次出现字符c的位置。

举例1:     

#include<stdio.h>

#include<string.h>

intmain()

{

    char a[17];

    char *ptr,c='r';

    strcpy(a,"This is a string");

    ptr=strchr(a,c);

    if(ptr)

        printf("The character %c is atposition: %s\n",c,ptr);

    else

        printf("The character was notfound\n");

    return 0;

}

输出结果:The character r is at position:ring

2、memset函数,初始化函数

memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法

函数原型:void*memset(void *s, int ch, size_t n);

       *s为数组名,ch为要填充的数,n为选择填充数组的长度(一般用sizeof(数组名))

举例1:填充字符

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

    char a[5];

    memset(a,'1',5);

    for(int i=0;i<5;i++)

    cout<<a[i]<<"";

    return 0;

}

输出结果:11111

举例2:填充整数0,只能是0

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

    int a[5];

    memset(a,0,sizeof(a));

    for(int i=0;i<5;i++)

    cout<<a[i]<<" ";

    return 0;

}

输出结果:0 0 0 0 0

3、memmove函数

函数原型:

void *memmove( void* dest, const void* src,size_t count );

功能:

由src所指内存区域复制count个字节到dest所指内存区域,如果src和dest出现重叠,函数会自动处理,返回dest的值。

举例1:将字符串移动

#include <stdio.h>

#include <string.h>

int main(void)

{

   char s[]="Golden Global View";

   memmove(s,s+7,strlen(s)+1-7);

   printf("%s",s);

   getchar();

   return 0;

}

输出结果:GlobalView

4、memcpy函数

举例1:将s中的字符串复制到字符数组d中

#include<stdio.h>

#include<string.h>

int main()

{

   char*s="GoldenGlobalView";

   char d[20];

   memcpy(d,s,(strlen(s)+1));

   printf("%s",d);

   getchar();

   return 0;

}

输出结果:GoldenGlobalView

举例2:将s中第6个字符开始的6个连续字符复制到d中。(从0开始)

#include<stdio.h>

#include<string.h>

int main()

{

   char *s="GoldenGlobalView";

   char d[20];

    memcpy(d,s+6,6);   //从第6个字符(V)开始复制,连续复制6个字符(View)

   d[6]='\0';                 

   printf("%s",d);

   return 0;

}

输出结果: Global

举例3:复制后覆盖原有部分数据

#include<stdio.h>

#include<string.h>

int main()

{

   char src[]="******************************";

   char dest[]="abcdefghijlkmnopqrstuvwxyz0123as6";

   printf("destinationbeforememcpy:%s\n",dest);

   memcpy(dest,src,strlen(src));

   printf("destinationaftermemcpy:%s\n",dest);

   return 0;

}

输出结果:destinationbefore memcpy:abcdefghijlkmnopqrstuvwxyz0123as6

destination after memcpy: ******************************as6

5、memchr函数,从buf所指内存区域的前count个字节查找字符ch。

函数原型:

extern void *memchr(const void *buf, intch, size_t count);

功能:

从buf所指内存区域的前count个字节查找字符ch。

6、strlen函数(正好是字符串中字符的个数)

举例1:

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

   char*s="GoldenGlobalView";

   cout<<strlen(s)<<endl;

   return 0;

}

输出结果:16

7、strrev函数(翻转字符串)

举例1:

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

   char s[]="WelcomeToBeijing";

   cout<<strrev(s)<<endl;

   return 0;

}

输出结果:nijieBoTemocleW

8、strupr(将字符串s1中小写字母转换为大写)

举例1:

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

   char s1[]="abcdef";

   char *s2=strupr(s1);

   cout<<s2<<endl;

   return 0;

}

输出结果:ABCDEF

9、strlwr(将字符串s1中大写字母转换为小写)

举例1:

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

   char s1[]="ABCDEF";

   char *s2=strlwr(s1);

   cout<<s2<<endl;

   return 0;

}

 输出结果:abcdef

10、strstr(函数搜索一个字符串在另一个字符串中的第一次出现)

举例1:

#include<stdio.h>

#include<string.h>

int main()

{

   char*s="GoldenGlobalView";

   char*l="lob";

   char*p;

   p=strstr(s,l);

    if(p)

       printf("%s",p);

   else

       printf("NotFound!");

   return 0;

}

输出结果:lobalView

11、strcat函数,字符串剪接(把src所指字符串添加到dest结尾处)

函数原型:

extern char *strcat(char *dest,char*src);

功能:

把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。

举例1:

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

   char d[20]="GoldenGlobal";

   char s[20]="View";

   strcat(d,s);

   cout<<d<<endl;

   return 0;

}

输出结果:GoldenGlobalView

12、strncat函数,剪接n个字符(把src所指字符串的前n个字符添加)

函数原型:

extern char *strncat(char *dest,char*src,int n);

功能:

把src所指字符串的前n个字符添加到dest结尾处(覆盖dest结尾处

的'\0')并添加'\0'。

举例1:

#include<iostream>

#include<cstring>

using namespace std;

int main()

{

   char d[20]="GoldenGlobal";

   char *s="ViewWinIDELibrary";

    strncat(d,s,5);

   cout<<d<<endl;

   return 0;

}

输出结果:GoldenGlobalViewW

13、strcpy函数,字符串复制

函数声明:

extern char *strcpy(char* dest, constchar *src);

功能:

把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间

注意:

src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针

14、strncpy函数,复制n个字符

函数原型:

char*strncpy(char*dest,char*src,size_tn);

功能:

复制字符串src中的内容(字符,数字、汉字....)到字符串dest中,复制多少由size_t的值决定,返回指向dest的指针。如果遇到空字符('\0')[1] ,则空字符后面全部为空(字符)

注意:

如:dest[]="Hell99iam!"; 

src[]="abc\0def";

strncpy(dest,src,5);

此时,dest区域是这样的:'a','b','c','\0','\0','9','i','a','m','!'

注意:\0,\0并不是添加在!的后面。

15、strcspn(顺序搜寻字符串s1与s2中第一个相同的字符)

举例1:

#include <stdio.h >

#include <string.h>

int main()

{

    char *s="Golden GlobalView";

    char *r="new";

    int n;

    n=strcspn(s,r);

    printf("The first char bothin s1 and s2 is: %c",s[n]);

    return 0;

}

输出结果:The first char both in s1 and s2 is: e

16、strcmp(字符串比较函数)

功能:

比较字符串s1和s2。

注意:

当s1<s2时,返回为负数

当s1=s2时,返回值=0

当s1>s2时,返回正数

举例1:

#include<stdio.h>

#include<string.h>

int main()

{  char*s1="Hello,Programmers!";

   char*s2="Hello,programmers!";

   int r;

   r=strcmp(s1,s2);

   if(!r)

       printf("s1ands2areidentical");

   else if(r<0)

       printf("s1lessthans2");

   else

       printf("s1greaterthans2");

return 0;}

输出结果:s1lessthans2

17、strncmp(指定比较的字符串长度函数)

函数原型:

int strncmp(char *str1, char *str2, intmaxlen);

注意:

当s1<s2时,返回为负数

当s1=s2时,返回值=0

当s1>s2时,返回正数

举例1:

#include<string.h>

#include<stdio.h>

int main()

{

   char *buf1="aaabbb",*buf2="bbbccc",*buf3="ccc";

   int ptr;

   ptr=strncmp(buf2,buf1,3);

   if(ptr>0)

       printf("buffer2 is greater than buffer1\n");

   else if(ptr<0)

       printf("buffer2 is less than buffer1\n");

   ptr=strncmp(buf2,buf3,3);

   if(ptr>0)

        printf("buffer2 is greater thanbuffer3\n");

   else if(ptr<0)

       printf("buffer2 is less than buffer3\n");

   return 0;

}

输出结果:

buffer2 is greater than buffer1

buffer2 is less than buffer3

18、strtok(分隔字符串函数)

函数原型:

char *strtok(char s[], const char*delim);

功能:

分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。

例如:strtok("abc,def,ghi",","),最后可以分割成为abc def ghi.

举例1:

#include<string.h>

#include<stdio.h>

int main()

{

    charinput[16]="abc,d,efg";

    char *p;

    p=strtok(input,",");

    while(p)

    {

        printf("%s\n",p);

        p=strtok(NULL,",");

    }

    return 0;

}

输出结果:abc

       d

       efg

19、memcpy(复制字符串函数)

函数原型:

void *memcpy(void *dest, const void *src,size_t n);

功能:

从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

举例1:将s中第13个字符开始的4个连续字符复制到d中。(从0开始)

#include<stdio.h>

#include<string.h>

int main()

{

    char s[]="GoldenGlobalView";

    char d[20];

    memcpy(d,s+12,4);//从第13个字符(V)开始复制,连续复制4个字符

    d[4]='\0';    //memcpy(d,s+14*sizeof(char),4*sizeof(char));也可

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

    return 0;

}

输出结果:View

20、reverse倒置字符串函数

功能:

倒置字符串

举例1:

#include<stdio.h>

#include<string.h>

void reverse(char s[])

{

 intc,j,i;

 for(i=0,j=strlen(s)-1;i<j;i++,j--)      //完成倒置功能,不包括字符串结束符'/0'

 {

 c=s[i];

 s[i]=s[j];

 s[j]=c;

 }

}

 

int main()                        //主函数,用于测试reverse函数的功能

{

 chars[]="123456";

 reverse(s);                      //调用倒置函数

 printf("%s\n",s);                 //输出倒置后的字符串

 return 0;

}

输出结果:654321

六、cctype头文件内函数

1、isdigit 函数,检查ch是否是数字

函数原型:

int isdigit(int ch);

功能:

检查ch是否是数字(0-9)

函数返回:

是返回1,否则返回0

举例1:

#include <stdio.h>

#include <ctype.h>

int main()

{

   char ch1='1';

   char ch2='a';

   if(isdigit(ch1)!=0)

       printf("%c is the ASCII number\n",ch1);

   else

       printf("%c is not the ASCII number\n",ch1);

   if(isdigit(ch2)!=0)

        printf("%c is the ASCIInumber\n",ch2);

   else

       printf("%c is not the ASCII number\n",ch2);

   return 0;

}

输出结果:

1 is the ASCII number

a is not the ASCII number

2、isalpha 函数,检查ch是否是字母

函数原型:

 int isalpha(int ch);

功能:

检查ch是否是字母

函数返回:

是返回1,否则返回0

举例1:

#include<stdio.h>

#include<ctype.h>

int main()

{

   char ch1='*';

   char ch2='a';

   if(isalnum(ch1)!=0)

       printf("%c is the ASCII number or alphebet\n",ch1);

   else

       printf("%c is not the ASCII number nor alphebet\n",ch1);

    if(isalnum(ch2)!=0)

       printf("%c is the ASCII number or alphebet\n",ch2);

   else

       printf("%c is not the ASCII number nor alphebet\n",ch2);

   return 0;

}

输出结果:

* is not the ASCII number nor alphabet

a is the ASCII number or alphabet

3、islower 函数,检查ch是否小写字母(a-z)

函数原型:

 int islower(int ch); 

功能:

检查ch是否小写字母(a-z)

函数返回:

是返回1,否则返回0

4、isupper函数,检测是否是大写字母(A-Z)

函数原型:

extern int isupper(int c);

功能:

判断字符c是否为大写英文字母

举例1:

#include <ctype.h>

#include <stdio.h>

int main()

{

   char Test[]="a1B2c3D4";

   char *pos;

   pos=Test;

   while(*pos!=0)

    {

       if(isupper(*pos))

           printf("%c",*pos);

       pos++;

    }

   printf("\n");

   return 0;

}

输出结果:

BD

5、ispunct函数,检查参数c是否为标点符号或特殊符号

函数原型:

int ispunct(int c)

功能:

检查参数c是否为标点符号或特殊符号

举例1:

#include<stdio.h>

#include <ctype.h>

int main()

{  char str[]="123c@ #FDsP[e?";

   int i;

   for(i=0;str[i]!=0;i++)

   if(ispunct(str[i])) printf("%c ",str[i]);

   return 0;

}

输出结果:@ # [ ?

6、isalnum函数,判断字符变量c是否为字母或数字

函数原型:

extern int isalnum(int c);

功能:

判断字符变量c是否为字母或数字

举例1:

#include<stdio.h>

#include <ctype.h>

int main()

{

   int c;

   c='a';

   printf("%c:%s\n",c,isalnum(c)?"yes":"no");

   c='7';

   printf("%c:%s\n",c,isalnum(c)?"yes":"no");

   c='@';

   printf("%c:%s\n",c,isalnum(c)?"yes":"no");

   return 0;

}

举例1:

a: yes

7: yes

@: no

7、tolower函数,把字符转换成小写字母,非字母字符不做出处理

函数原型:

int tolower(int c);

功能:

把字符转换成小写字母,非字母字符不做出处理

举例1:

#include <iostream>

#include <string>

#include <cctype>

using namespace std;

int main()

{

   string str= "THIS IS A STRING";

   for (int i=0; i <str.size(); i++)

      str[i] = tolower(str[i]);

   cout<<str<<endl;

   return 0;

}

输出结果:

this is a string

8、toupper函数,把字符转换成大写字母,非字母字符不做出处理

函数原型:

extern int toupper(int c);

功能:

把字符转换成大写字母,非字母字符不做出处理

举例1:

#include <stdio.h>

#include <string.h>

#include <ctype.h>

int main()

{

   char *s="Hello, World!";

   int i;

   printf("%s\n",s);

   for(i=0;i<strlen(s);i++)

    {

       putchar(toupper(s[i]));

    }

   return 0;

}

输出结果:

Hello, World!

HELLO,WORLD!

七、STL模板

1、正、逆序迭代器(正序、逆序输出,按键盘输入顺序)

举例1:

#include<vector>

#include<iostream>

using namespace std;

int main()

{

   int a[4];

   vector<int> v;                         //一个存放int元素的向量,一开始里面没有元素

                                   //inta,b,c,d;

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

   {cin>>a[i];

   v.push_back(a[i]);}                    // 将值带入向量

                                   //v.push_back(b);

                                   //v.push_back(c);

                                   //v.push_back(d);

   vector<int>::const_iterator i;            //常量迭代器

   for(i=v.begin();i!=v.end();i++)

       cout<<*i<<",";

   cout<<endl;

   vector<int>::reverse_iterator r;          //反向迭代器

   for(r=v.rbegin();r!=v.rend();r++)

       cout<<*r<<".";

   cout<<endl;

   vector<int>::iterator j;                  //非常量迭代器

   for(j=v.begin();j!=v.end();j++)

       *j=100;

   for(i=v.begin();i!=v.end();i++)

       cout<<*i<<".";

   return 0;

}

输入:1 2 3 4

输出结果:1,2,3,4,

         4.3.2.1.

          100.100.100.100.

2、set_union(获得两个集合的并集)

举例1:

#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

int main ()

{

   int first[] = {5,10,15,20,25};

   int second[] = {50,40,30,20,10};

   vector<int> v(10);

   vector<int>::iterator it;

   sort (first,first+5);

   sort (second,second+5);

   it=set_union (first, first+5, second, second+5, v.begin());

   cout << "union has " << int(it - v.begin())<< " elements.\n";

   return 0;

}

输出结果:union has8 elements.

3、set_intersection(获得两个集合的交集)

举例1:

#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

int main(int argc, char** argv)

{

   int A[] = {5,10,15,20,25};

    int B[] = {50,40,30,20,10};

   int C[10] = {0};

   size_t size_A, size_B, size_C;

   vector<int> v;

   vector<int>::iterator it;

   size_A = sizeof(A)/sizeof(A[0]);

   size_B = sizeof(B)/sizeof(B[0]);

   size_C = sizeof(C)/sizeof(C[0]);

   v.resize(size_A+size_B);

   sort (A, A + size_A);

   sort (B, B + size_B);

   it = set_intersection (A, A+size_A, B, B+size_B, v.begin());

   v.resize(it-v.begin());

   cout << "The intersection has " << (v.size())<< " elements:" << endl;

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

       cout << ' ' << *it;

   cout << endl;

   if(size_C < v.size())

   {

     cout << "Array C is too small." << endl;

   }

  else

   {

      copy(v.begin(), v.end(), C);

      cout << "The array of C is:" << endl;

      for (int i = 0; i < v.size(); i ++)

          cout << ' ' << C[i];

      cout << endl;

   }

  return 0;

}

输出结果:

The intersection has 2 elements:

 1020

The array of C is:

10 20

4、unique(删除所有相邻的重复元素

头文件:

#include <vector>

功能:

删除所有相邻的重复元素

举例1:

#include <cassert>

#include <iostream>

#include <algorithm>

#include <vector>

#include <string>

#include <iterator>

using namespace std;

int main()

{

   const int N=11;

   int array1[N]={1,2,0,3,3,0,7,7,7,0,8};

   vector<int> vector1;

   for (int i=0;i<N;++i)

        vector1.push_back(array1[i]);

 

   vector<int>::iterator new_end;

   new_end=unique(vector1.begin(),vector1.end());    //"删除"相邻的重复元素

   assert(vector1.size()==N);   //assert相当于if,在#include <cassert>头文件中

 

   vector1.erase(new_end,vector1.end()); //删除(真正的删除)重复的元素

   copy(vector1.begin(),vector1.end(),ostream_iterator<int>(cout,""));

   cout<<endl;

   return 0;

}

输出结果:

1 2 0 3 0 7 0 8

5、insert函数,向迭代器里输入数据

举例1:

#include<iostream>

#include<cstring>

#include<sstream>

#include<set>

using namespace std;

set<string> dict;

int main()

{

   string s="aaaaaa",buf;

   stringstream ss(s);

   while(ss>>buf)

   dict.insert(buf);

   for(set<string>::iterator it =dict.begin(); it!=dict.end();++it)

   cout<<*it<<"\n";

   return 0;

}

输出结果:

Aaaaaa

6、deque双端队列,支持首尾两端插入、删除

头文件:

#include <deque>

功能:

支持首尾两端插入、删除

举例1:

#include<iostream>

#include<deque>

using namespace std;

int main()

{

   deque<int> c;

   c.push_front(1);

   c.push_back(2);

   c.push_front(3);

   for(int i=0;i<c.size();i++)

    {

       cout<<c[i]<<" ";

    }

   return 0;

}

输出结果:

3 1 2

方法:

c.assign(beg,end) 将[beg; end)区间中的数据赋值给c。

c.assign(n,elem) 将n个elem的拷贝赋值给c。

c.at(idx) 传回索引idx所指的数据,如果idx越界,抛出out_of_range。

c.back() 返回容器c的最后一个元素的引用。如果c为空,则该操作未定义。

c.begin() 传回迭代器中的第一个数据地址。

c.clear() 移除容器中所有数据。

c.empty() 判断容器是否为空。

c.end() 返回一个迭代器,它指向容器c的最后一个元素的下一位置。

c.erase(pos) 删除pos位置的数据,传回下一个数据的位置。

c.erase(beg,end) 删除[beg,end)区间的数据,传回下一个数据的位置。

c.front() 返回容器c的第一个元素的引用。如果c为空,则该操作为空。

get_allocator 使用构造函数返回一个拷贝。

c.insert(pos,elem) 在pos位置插入一个elem拷贝,传回新数据位置

c.insert(pos,n,elem) 在pos位置插入>n个elem数据。无返回值

c.insert(pos,beg,end) 在pos位置插入在[beg,end)区间的数据。无返回值

c.max_size() 返回容器c可容纳的最多元素个数。

c.pop_back() 删除最后一个数据。

c.pop_front() 删除头部数据。

c.push_back(elem) 在尾部加入一个数据。

c.push_front(elem) 在头部插入一个数据。

c.rbegin() 返回一个逆序迭代器,它指向容器c的最后一个元素。

c.rend() 返回一个逆序迭代器,它指向容器c的第一个元素的前一个位置。

c.resize(num) 重新指定队列的长度。

c.size() 返回容器中实际数据的个数。

c.swap(c2) 交换容器c和c2中的所有元素。

swap(c1,c2) 交换容器c1和c2中的所有元素,和上一方法相似。

7、set集合

举例1:

#include<iostream>

#include<set>

using namespace std;

int main()

{

   set<int> set1;

    for(int i=0; i<10; ++i)

    set1.insert(i);

   for(set<int>::iterator p=set1.begin();p!=set1.end();++p)

   cout<<*p<<"";

   if(set1.insert(3).second)//把3插入到set1中

   //插入成功则set1.insert(3).second返回1,否则返回0

   //此例中,集中已经有3这个元素了,所以插入将失败

   cout<<"set insert success";

   else

   cout<<"set insert failed";

   int a[] = {4, 1, 1, 1, 1, 1, 0, 5, 1, 0};

   multiset<int> A;

   A.insert(set1.begin(),set1.end());

   A.insert(a,a+10);

   cout<<endl;

   for(multiset<int>::iterator p=A.begin();p!=A.end();++p)

   cout<<*p<<" ";

   cin.get();

   return 0;

}

输出结果:

0123456789 set insert failed

0 0 0 1 1 1 1 1 1 1 2 3 4 4 5 5 6 7 8 9

方法:

begin() 返回指向第一个元素的迭代器

clear() 清除所有元素

count() 返回某个值元素的个数

empty() 如果集合为空,返回true(真)

end() 返回指向最后一个元素之后的迭代器,不是最后一个元素

equal_range() 返回集合中与给定值相等的上下限的两个迭代器

erase() 删除集合中的元素

find() 返回一个指向被查找到元素的迭代器

get_allocator() 返回集合的分配器

insert() 在集合中插入元素

lower_bound() 返回指向大于(或等于)某值的第一个元素的迭代器

key_comp() 返回一个用于元素间值比较的函数

max_size() 返回集合能容纳的元素的最大限值

rbegin() 返回指向集合中最后一个元素的反向迭代器

rend() 返回指向集合中第一个元素的反向迭代器

size() 集合中元素的数目

swap() 交换两个集合变量

upper_bound() 返回大于某个值元素的迭代器

value_comp() 返回一个用于比较元素间的值的函数

八、algorithm头文件内函数

1、sort函数(排序)

举例1:对数组a正序、降序排序

#include<iostream>

#include<algorithm>

using namespace std;

int cmp( const int &a, const int &b)

{

if( a > b )

    return 1;

else

    return 0;

}

int main()

{

   int a[]={3,4,12,1,23,2,1,4};

   sort(a,a+8);                //是对数组a正序排序

   for(int i=0;i<8;i++)

    {

       cout<<a[i]<<" ";

    }

   cout<<endl;

   sort(a,a+8,cmp);            //是对数组a降序排序

   for(int i=0;i<8;i++)

    {

       cout<<a[i]<<" ";

    }

return 0;

}

输出结果:

1 1 2 3 4 4 12 23

23 12 4 4 3 2 1 1

另:也可以用该方法从大到小排序

bool cmp(int a,int b)

{

   return a>b;

}

2、next_permutation函数(按字典序求下一个的全排列)

举例1:(int型)

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   int a[] = {2,1,3};

   while (next_permutation(a, a+3))

    {

       cout << a[0] << " " << a[1] << "" << a[2] << endl;

    }

   return 0;

}

输出结果:2 1 3

2 3 1

           3 1 2

           3 2 1

举例2:(string型)

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   string str;

   cin >> str;

   sort(str.begin(), str.end());

   do

    {

       cout << str <<" ";

   }while (next_permutation(str.begin(), str.end()));

   return 0;

}

输入:abc

输出结果:abc acbbac bca cab cba

3、prev_permutation(按字典序求上一个的全排列)

用法:

与next_permutation相同

4、adjacent_find函数,查找两个相邻的等价元素

功能:

查找两个相邻的等价元素

举例1:

#include <iostream>

#include <algorithm>

#include <vector>

using namespace std;

bool myfunction (int i, int j)

{

    return (i==j);

}

int main ()

{

   int myints[] = {10,20,30,30,20,10,10,20};

   vector<int> myvector (myints,myints+8);

   vector<int>::iterator it;

   it = adjacent_find (myvector.begin(), myvector.end());

   if (it!=myvector.end())

   cout << "the first consecutive repeated elements are: "<< *it << endl;

   it = adjacent_find (++it, myvector.end(), myfunction);

   if (it!=myvector.end())

   cout << "the second consecutive repeated elements are: "<< *it << endl;

   return 0;

}

5、count函数,在序列中统计某个值出现的次数

举例1:

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   int a[1000]={1,2,3,3,3,4,4,5};

   int y=count(a,a+8,3);    //(数组名,查询的数组长度,查询个数的数字)

   cout<<"number of times "<<y<<endl;

   return 0;

}

输出结果:

number of times 3

举例2:

#include<iostream>

#include<vector>

#include<algorithm>

using namespace std;

int main()

{

   int ival , searchValue;

   vector<int> ivec;

   cout<<"Enter some integers(Ctrl+Z to end):"<<endl;

   while(cin >> ival)

       ivec.push_back(ival);

    cin.clear();// 使输入流重新有效

   cout<<"Enter an integer you want to search:"<<endl;

   cin>>searchValue;

   cout<<count(ivec.begin() , ivec.end() , searchValue)

       <<"  elements in thevector have value "

       <<searchValue<<endl;

   return 0;

}

6、count_if函数,在序列中统计与某谓词匹配的次数

举例1:

#include <vector>

#include <algorithm>

#include <iostream>

using namespace std;

bool greater10(int value)

{

   return value >10;

}

 

int main()

{

   vector<int> v1;

   vector<int>::iterator Iter;

   v1.push_back(10);

    v1.push_back(20);

   v1.push_back(10);

   v1.push_back(40);

   v1.push_back(10);

   cout << "v1 : ";

   for (Iter = v1.begin(); Iter != v1.end(); Iter++)

      cout << *Iter << " ";

   cout << endl;

 

   vector<int>::size_type result1 = count_if(v1.begin(), v1.end(), greater10);  //count_if算法返回使谓词函数返回条件成立的元素个数

   cout << "The number of elements in v1greater than 10 is:"<< result1 << "." <<endl;

   return 0;

}

输出结果:

v1 : 10 20 10 40 10

The number of elements in v1 greater than10 is: 2.

7、find函数,查找某个数出现的位置

举例1:

#include<vector>

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   int array[10]={10,20,30,40};

   vector<int> v;

   v.push_back(1);

   v.push_back(2);

   v.push_back(3);

   v.push_back(4);

   vector<int>::iterator p;

   p=find(v.begin(),v.end(),3);         //p=从头找到尾,找3

   if(p!=v.end())         //如果p还没到结尾的时候,就找到3了,则输出3

       cout<<*p<<endl;

   p=find(v.begin(),v.end(),9);             //p=从头找到尾,找9

   if(p==v.end())        //如果p到最后了,也就是没找到,则输出not found

       cout<<"not found "<<endl;

   p=find(v.begin()+1,v.end()-2,1);       

   if(p!=v.end())

       cout<<*p<<endl;

   int *pp=find(array,array+4,20);

       cout<<*pp<<endl;

   return 0;

}

输出结果:3

           not found

           3

         20

举例2:

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   int a[]={1,2,2,3,3,4,5};

   int x=find(a,a+7,3)-a;

   cout<<x+1<<endl;

   return 0;

}

输出结果:

4

8、lower_bound(查找大于或者等于x的第一个位置)

头文件:

不用STL模板时

#include<algorithm>

用STL模板时

#include<algorithm>

#include <vector>

功能:

查找大于或者等于x的第一个位置

注意:

必须是先排好序的数组

举例1:

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   int a[100]={1,2,23,33,45,56,123};

   int p=lower_bound(a,a+7,35)-a;

   cout<<35<<" found at"<<p+1<<endl;

   return 0;

}

输出结果:35 foundat 5

举例2:

#include <iostream>

#include <algorithm>

#include <functional>

#include <vector>

using namespace std;

int main()

{

   const int VECTOR_SIZE = 8 ;

   typedef vector<int> IntVector ;

   typedef IntVector::iterator IntVectorIt ;

   IntVector Numbers(VECTOR_SIZE) ;

   IntVectorIt start, end, it, location ;

   Numbers[0] = 4 ;

   Numbers[1] = 10;

   Numbers[2] = 11 ;

   Numbers[3] = 30 ;

   Numbers[4] = 69 ;

   Numbers[5] = 70 ;

   Numbers[6] = 96 ;

   Numbers[7] = 100;

    start = Numbers.begin() ;

   end = Numbers.end() ;

   cout << "Numbers { " ;

   for(it = start; it != end; it++)

       cout << *it << " " ;

   cout << " }\n" << endl ;

   location = lower_bound(start, end, 30) ;

   cout << "First location element 10 can beinserted in Numbers is:"<< location - start+1<< endl ;

   return 0;

}

输出结果:

Numbers { 4 10 11 30 69 70 96 100 }

"First location element 10 can beinserted in Numbers is: 4

9、upper_bound(查找大于x的第一个位置)

用法:

与lower_bound()相同

功能:

查找大于x的第一个位置

注意:

必须是先排好序的数组

举例1:

#include<iostream>

#include<algorithm>

using namespace std;

int main()

{

   int a[100]={1,2,23,33,45,56,123};

   int p=upper_bound(a,a+7,2)-a;

   cout<<2<<" found at "<<p+1<<endl;

   return 0;

}

输出结果:2 foundat 3

 

九、iomanip头文件内函数

1、

setiosflags(ios::fixed) 固定的浮点显示

setiosflags(ios::scientific) 指数表示

setiosflags(ios::left) 左对齐

setiosflags(ios::right) 右对齐

setiosflags(ios::skipws) 忽略前导空白

setiosflags(ios::uppercase) 16进制数大写输出

setiosflags(ios::lowercase) 16进制小写输出

setiosflags(ios::showpoint) 强制显示小数点

setiosflags(ios::showpos) 强制显示符号

2、

dec 置基数为10 相当于"%d"

hex 置基数为16 相当于"%X"

oct 置基数为8 相当于"%o"

setfill( 'c' ) 设填充字符为c

setprecision( n ) 设显示有效数字为n位

setw( n ) 设域宽为n个字符

3、

setbase(int n) : 将数字转换为 n 进制.

举例:

cout<<setbase(8)<<setw(5)<<255<<endl;

cout<<setbase(10)<<setw(5)<<255<<endl;

cout<<setbase(16)<<setw(5)<<255<<endl

输出结果:

(空格)(空格)377

(空格)(空格) 255

(空格)(空格)(空格) f f

4、

#include<iomanip>

   cout<<setprecision(位数);                       //控制总位数

   cout<<setiosflags(ios::fixed)<<setprecision(位数);    //控制小数点后位数

十、cstdlib头文件内函数

1、atoi函数,把字符串转换成整型数

头文件:

#include <stdlib.h>

功能:

把字符串转换成整型数

举例1:

#include<stdlib.h>

#include<stdio.h>

int main()

{

   float n;

   char const* str="12345.67";

   n=atoi(str);

   printf("string = %s integer = %f \n",str,n);

   return 0;

}

输出结果:

string = 12345.67 integer = 12345.000000

举例2:

#include<stdlib.h>

#include<stdio.h>

int main()

{

   char a[]="-100";

   char b[]="123";

   int c;

   c=atoi(a)+atoi(b);

   printf("c=%d\n",c);

   return 0;

}

输出结果:

c=23

2、atof函数,把字符串转换成浮点数

用法:

与atoi相同

3、atol函数,把字符串转换成长整型数

用法:

与atoi相同

4、itoa函数,把整型数转换成字符串

头文件:

#include <stdlib.h>

功能:;

把整型数转换成字符串

举例1:

#include<stdlib.h>

#include<stdio.h>

int main()

{

   int number=123456;

   char string[25];

   itoa(number,string,10);

   printf("integer = %d string = %s\n",number,string);

   return 0;

}

输出结果:

integer = 123456string = 123456

5、gcvt函数,把浮点数转换成字符串

功能:

把浮点数转换成字符串

举例1:

#include<iostream>

#include<cstdlib>

using namespace std;

int main()

{

   double number=123456.67;

   char a[100];

   gcvt(number,10,a);

   cout<<"integer= "<<number<<" string="<<a<<endl;

   return 0;

}

输出结果:

integer= 123457 string= 123456.67

十一、sstream头文件内函数

1、stringstream函数

举例1:可以作为将数字和字符串相互转化的工具

#include<iostream>

#include<cstring>

#include<sstream>

using namespace std;

int main()

{

   std::string name("12345");

   int age = 27;

   stringstream os;

   os << age;

   os >> name;

   // name:27

   cout<<name<<endl;

   return 0;

}

输出结果;

27

举例2:2.支持char*的输入和输出

#include<iostream>

#include<cstring>

#include<sstream>

using namespace std;

int main()

{

   stringstream ss_stream;

   char sz_buf[5];

   ss_stream << 88888;

   ss_stream >> sz_buf; // 直接将数输出到sz_buf字符数组中

   for(int i=0;i<5;i++)

   cout<<sz_buf[i]<<" ";

   cout<<endl;

   return 0;

}

输出结果:

8 8 8 8 8

十二、查找

1、快速选择问题(快速查找排序后第K个数),程序优化,应对大量数据时用

问题描述:

输入n个整数和一个正整数k(1<=k<=n),输出这些整数从小到大排序后的第k个(例如,k=1就是最小值)。n<=10*e7

举例:

#include<iostream>

#include<cmath>

#include<cstdlib>

using namespace std;

// 快速选择,平均时间复杂度O(N)

typedef int DataType;

#defineSWAP(x,y)  {DataType t=x;x=y;y=t;}

intquickSelect( DataType* A, int beg, int end, int K )

{

       DataType pivot;

       int i, j;

 

       if ( end - beg + 1 < K )  // error

       {

              cout<<"error!"<<endl;

              exit(0);

       }

 

       pivot = A[beg];

       i = beg;

       j = end + 1;

 

       // 将数组分为小于pivot和大于pivot的两部分

       for ( ;; )

       {

              while(A[++i] < pivot );

              while(A[--j] > pivot );

              if( i > j ) break;

              SWAP(A[i], A[j] );

       }

       SWAP( A[beg], A[j] );

 

       if ( j - beg  == K-1 )  // 如果小于pivot的数目刚好为K-1个,这返回该pivot

              returnA[j];

       else if ( j - beg >= K ) // 否则,如果小于pivot的数目大于K-1个,则返回该部分中第K大的数

              returnquickSelect( A, beg, j-1, K );

       else

              returnquickSelect( A, j+1, end, K-(j-beg+1) );

}

 

int main()

{

   //freopen("a.txt","r",stdin);

   int a[]={34,34,4234,8,445,6481,2387,123,86,514};

   cout<<quickSelect(a,0,10,8)<<endl;

   return 0;

}

输出结果:

2387

2、二分查找

举例:

#include<iostream>

using namespace std;

int binary(int *a,int n,int key)

{

   int l=0,r=n;

   while(l<r)

    {

       int mid=l+(r-l)/2;   //避免(l+r)溢出

       if(a[mid]==key)

           return mid;

       if(a[mid]<key)

           l=mid+1;

       else

           r=mid;

    }

   return -1;

}

int main()

{

   int a[]={1,3,4,5,6,7,8};

   cout<<binary(a,7,7)+1<<endl;    //因为是从0开始的

   return 0;

}

 

十三、几何

1、几何公式

1、三角形:

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))

 

2、四边形:

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为半周长

 

3、正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))

 

4、圆:

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

 

5、棱柱:

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

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

3. 全面积 T=S+2A

 

6、棱锥:

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

(以下对正棱锥)

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

3. 全面积 T=S+A

 

7、棱台:

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

 

8、圆柱:

1. 侧面积 S=2PIrh

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

3. 体积 V=PIr^2h

 

9、圆锥:

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

2. 侧面积 S=PIrl

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

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

 

10、圆台:

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

 

11、球:

1. 全面积 T=4PIr^2

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

 

12、球台:

1. 侧面积 S=2PIrh

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

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

 

13、球扇形:

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

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

2、点、线之间的运算

//浮点几何函数库

#include <math.h>

#define eps 1e-8

#define zero(x)(((x)>0?(x):-(x))<eps)

struct point{double x,y;};

struct line{point a,b;};

 

1、计算cross product (P1-P0)x(P2-P0)

double xmult(point p1,point p2,point p0){

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

}

double xmult(double x1,double y1,doublex2,double y2,double x0,double y0){

       return(x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);

}

 

2、计算dot product (P1-P0).(P2-P0)

double dmult(point p1,point p2,point p0){

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

}

double dmult(double x1,double y1,doublex2,double y2,double x0,double y0){

       return(x1-x0)*(x2-x0)+(y1-y0)*(y2-y0);

}

 

3、两点距离

double distance(point p1,point p2){

       returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));

}

double distance(double x1,double y1,doublex2,double y2){

       returnsqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

}

 

4、判三点共线

int dots_inline(point p1,point p2,pointp3){

       returnzero(xmult(p1,p2,p3));

}

int dots_inline(double x1,double y1,doublex2,double y2,double x3,double y3){

       returnzero(xmult(x1,y1,x2,y2,x3,y3));

}

 

5、判点是否在线段上,包括端点

int dot_online_in(point p,line l){

       returnzero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;

}

int dot_online_in(point p,point l1,pointl2){

       returnzero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;

}

int dot_online_in(double x,double y,doublex1,double y1,double x2,double y2){

       returnzero(xmult(x,y,x1,y1,x2,y2))&&(x1-x)*(x2-x)<eps&&(y1-y)*(y2-y)<eps;

}

 

6、判点是否在线段上,不包括端点

int dot_online_ex(point p,line l){

       returndot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));

}

int dot_online_ex(point p,point l1,pointl2){

       returndot_online_in(p,l1,l2)&&(!zero(p.x-l1.x)||!zero(p.y-l1.y))&&(!zero(p.x-l2.x)||!zero(p.y-l2.y));

}

int dot_online_ex(double x,double y,doublex1,double y1,double x2,double y2){

       returndot_online_in(x,y,x1,y1,x2,y2)&&(!zero(x-x1)||!zero(y-y1))&&(!zero(x-x2)||!zero(y-y2));

}

 

7、判两点在线段同侧,点在线段上返回0

int same_side(point p1,point p2,line l){

       returnxmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;

}

int same_side(point p1,point p2,pointl1,point l2){

       returnxmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;

}

 

8、判两点在线段异侧,点在线段上返回0

int opposite_side(point p1,point p2,linel){

       returnxmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;

}

int opposite_side(point p1,point p2,pointl1,point l2){

       returnxmult(l1,p1,l2)*xmult(l1,p2,l2)<-eps;

}

 

9、判两直线平行

int parallel(line u,line v){

       returnzero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));

}

int parallel(point u1,point u2,pointv1,point v2){

       returnzero((u1.x-u2.x)*(v1.y-v2.y)-(v1.x-v2.x)*(u1.y-u2.y));

}

 

10、判两直线垂直

int perpendicular(line u,line v){

       returnzero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));

}

int perpendicular(point u1,point u2,pointv1,point v2){

       returnzero((u1.x-u2.x)*(v1.x-v2.x)+(u1.y-u2.y)*(v1.y-v2.y));

}

 

11、判两线段相交,包括端点和部分重合

int intersect_in(line u,line v){

       if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))

              return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);

       returndot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);

}

int intersect_in(point u1,point u2,pointv1,point v2){

       if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))

              return!same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);

       returndot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);

}

 

12、判两线段相交,不包括端点和部分重合

int intersect_ex(line u,line v){

       returnopposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);

}

int intersect_ex(point u1,point u2,pointv1,point v2){

       returnopposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);

}

 

13、计算两直线交点,注意事先判断直线是否平行!

//线段交点请另外判线段相交(同时还是要判断是否平行!)

point intersection(line u,line v){

       pointret=u.a;

       doublet=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))

                     /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));

       ret.x+=(u.b.x-u.a.x)*t;

       ret.y+=(u.b.y-u.a.y)*t;

       returnret;

}

point intersection(point u1,point u2,pointv1,point v2){

       pointret=u1;

       doublet=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))

                     /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));

       ret.x+=(u2.x-u1.x)*t;

       ret.y+=(u2.y-u1.y)*t;

       returnret;

}

 

14、点到直线上的最近点

point ptoline(point p,line l){

       pointt=p;

       t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;

       returnintersection(p,t,l.a,l.b);

}

point ptoline(point p,point l1,point l2){

       pointt=p;

       t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;

       returnintersection(p,t,l1,l2);

}

 

15、点到直线距离

double disptoline(point p,line l){

       returnfabs(xmult(p,l.a,l.b))/distance(l.a,l.b);

}

double disptoline(point p,point l1,pointl2){

       returnfabs(xmult(p,l1,l2))/distance(l1,l2);

}

double disptoline(double x,double y,doublex1,double y1,double x2,double y2){

       returnfabs(xmult(x,y,x1,y1,x2,y2))/distance(x1,y1,x2,y2);

}

 

16、点到线段上的最近点

point ptoseg(point p,line l){

       pointt=p;

       t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;

       if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)

              returndistance(p,l.a)<distance(p,l.b)?l.a:l.b;

       returnintersection(p,t,l.a,l.b);

}

point ptoseg(point p,point l1,point l2){

       pointt=p;

       t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;

       if(xmult(l1,t,p)*xmult(l2,t,p)>eps)

              returndistance(p,l1)<distance(p,l2)?l1:l2;

       returnintersection(p,t,l1,l2);

}

 

17、点到线段距离

double disptoseg(point p,line l){

       pointt=p;

       t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;

       if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)

              returndistance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);

       returnfabs(xmult(p,l.a,l.b))/distance(l.a,l.b);

}

double disptoseg(point p,point l1,pointl2){

       pointt=p;

       t.x+=l1.y-l2.y,t.y+=l2.x-l1.x;

       if(xmult(l1,t,p)*xmult(l2,t,p)>eps)

              returndistance(p,l1)<distance(p,l2)?distance(p,l1):distance(p,l2);

       returnfabs(xmult(p,l1,l2))/distance(l1,l2);

}

 

18、矢量V以P为顶点逆时针旋转angle并放大scale倍

point rotate(point v,point p,doubleangle,double scale){

       pointret=p;

       v.x-=p.x,v.y-=p.y;

       p.x=scale*cos(angle);

       p.y=scale*sin(angle);

       ret.x+=v.x*p.x-v.y*p.y;

       ret.y+=v.x*p.y+v.y*p.x;

       returnret;

}

3、凸边形面积

#include <math.h>

struct point{double x,y;};

 

1、计算cross product (P1-P0)x(P2-P0)

double xmult(point p1,point p2,point p0){

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

}

double xmult(double x1,double y1,doublex2,double y2,double x0,double y0){

       return(x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);

}

 

2、计算三角形面积,输入三顶点

double area_triangle(point p1,pointp2,point p3){

       returnfabs(xmult(p1,p2,p3))/2;

}

double area_triangle(double x1,doubley1,double x2,double y2,double x3,double y3){

       returnfabs(xmult(x1,y1,x2,y2,x3,y3))/2;

}

 

3、计算三角形面积,输入三边长

double area_triangle(double a,doubleb,double c){

       doubles=(a+b+c)/2;

       returnsqrt(s*(s-a)*(s-b)*(s-c));

}

 

4、计算多边形面积,顶点按顺时针或逆时针给出

double area_polygon(int n,point* p){

       doubles1=0,s2=0;

       inti;

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

              s1+=p[(i+1)%n].y*p[i].x,s2+=p[(i+1)%n].y*p[(i+2)%n].x;

       returnfabs(s1-s2)/2;

}

 

4、球面

#include <math.h>

const double pi=acos(-1);

 

1、计算圆心角lat表示纬度,-90<=w<=90,lng表示经度

//返回两点所在大圆劣弧对应圆心角,0<=angle<=pi

double angle(double lng1,double lat1,doublelng2,double lat2){

       doubledlng=fabs(lng1-lng2)*pi/180;

       while(dlng>=pi+pi)

              dlng-=pi+pi;

       if(dlng>pi)

              dlng=pi+pi-dlng;

       lat1*=pi/180,lat2*=pi/180;

       returnacos(cos(lat1)*cos(lat2)*cos(dlng)+sin(lat1)*sin(lat2));

}

 

2、计算距离,r为球半径

double line_dist(double r,doublelng1,double lat1,double lng2,double lat2){

       doubledlng=fabs(lng1-lng2)*pi/180;

       while(dlng>=pi+pi)

              dlng-=pi+pi;

       if(dlng>pi)

              dlng=pi+pi-dlng;

       lat1*=pi/180,lat2*=pi/180;

       returnr*sqrt(2-2*(cos(lat1)*cos(lat2)*cos(dlng)+sin(lat1)*sin(lat2)));

}

 

3、计算球面距离,r为球半径

inline double sphere_dist(double r,doublelng1,double lat1,double lng2,double lat2){

       returnr*angle(lng1,lat1,lng2,lat2);

}

5、三角形

#include <math.h>

struct point{double x,y;};

struct line{point a,b;};

 

double distance(point p1,point p2){

       returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));

}

 

point intersection(line u,line v){

       pointret=u.a;

       doublet=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))

                     /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));

       ret.x+=(u.b.x-u.a.x)*t;

       ret.y+=(u.b.y-u.a.y)*t;

       returnret;

}

 

1、外心

point circumcenter(point a,point b,pointc){

       lineu,v;

       u.a.x=(a.x+b.x)/2;

       u.a.y=(a.y+b.y)/2;

       u.b.x=u.a.x-a.y+b.y;

       u.b.y=u.a.y+a.x-b.x;

       v.a.x=(a.x+c.x)/2;

       v.a.y=(a.y+c.y)/2;

       v.b.x=v.a.x-a.y+c.y;

       v.b.y=v.a.y+a.x-c.x;

       returnintersection(u,v);

}

 

2、内心

point incenter(point a,point b,point c){

       lineu,v;

       doublem,n;

       u.a=a;

       m=atan2(b.y-a.y,b.x-a.x);

       n=atan2(c.y-a.y,c.x-a.x);

       u.b.x=u.a.x+cos((m+n)/2);

       u.b.y=u.a.y+sin((m+n)/2);

       v.a=b;

       m=atan2(a.y-b.y,a.x-b.x);

       n=atan2(c.y-b.y,c.x-b.x);

       v.b.x=v.a.x+cos((m+n)/2);

       v.b.y=v.a.y+sin((m+n)/2);

       returnintersection(u,v);

}

 

3、垂心

point perpencenter(point a,point b,pointc){

       lineu,v;

       u.a=c;

       u.b.x=u.a.x-a.y+b.y;

       u.b.y=u.a.y+a.x-b.x;

       v.a=b;

       v.b.x=v.a.x-a.y+c.y;

       v.b.y=v.a.y+a.x-c.x;

       returnintersection(u,v);

}

 

4、重心

//到三角形三顶点距离的平方和最小的点

//三角形内到三边距离之积最大的点

point barycenter(point a,point b,point c){

       lineu,v;

       u.a.x=(a.x+b.x)/2;

       u.a.y=(a.y+b.y)/2;

       u.b=c;

       v.a.x=(a.x+c.x)/2;

       v.a.y=(a.y+c.y)/2;

       v.b=b;

       returnintersection(u,v);

}

 

5、费马点,到三角形三顶点距离之和最小的点

point fermentpoint(point a,point b,pointc){

       pointu,v;

       doublestep=fabs(a.x)+fabs(a.y)+fabs(b.x)+fabs(b.y)+fabs(c.x)+fabs(c.y);

       inti,j,k;

       u.x=(a.x+b.x+c.x)/3;

       u.y=(a.y+b.y+c.y)/3;

       while(step>1e-10)

              for (k=0;k<10;step/=2,k++)

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

                            for (j=-1;j<=1;j++){

                                   v.x=u.x+step*i;

                                   v.y=u.y+step*j;

                                   if(distance(u,a)+distance(u,b)+distance(u,c)>distance(v,a)+distance(v,b)+distance(v,c))

                                          u=v;

                            }

       returnu;

}

6、三维几何

//三维几何函数库

#include <math.h>

#define eps 1e-8

#define zero(x)(((x)>0?(x):-(x))<eps)

struct point3{double x,y,z;};

struct line3{point3 a,b;};

struct plane3{point3 a,b,c;};

 

1、计算cross product U x V

point3 xmult(point3 u,point3 v){

       point3ret;

       ret.x=u.y*v.z-v.y*u.z;

       ret.y=u.z*v.x-u.x*v.z;

       ret.z=u.x*v.y-u.y*v.x;

       returnret;

}

 

2、计算dot product U . V

double dmult(point3 u,point3 v){

       returnu.x*v.x+u.y*v.y+u.z*v.z;

}

 

3、矢量差 U - V

point3 subt(point3 u,point3 v){

       point3ret;

       ret.x=u.x-v.x;

       ret.y=u.y-v.y;

       ret.z=u.z-v.z;

       returnret;

}

 

4、取平面法向量

point3 pvec(plane3 s){

       returnxmult(subt(s.a,s.b),subt(s.b,s.c));

}

point3 pvec(point3 s1,point3 s2,point3 s3){

       returnxmult(subt(s1,s2),subt(s2,s3));

}

 

5、两点距离,单参数取向量大小

double distance(point3 p1,point3 p2){

       returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z));

}

 

6、向量大小

double vlen(point3 p){

       returnsqrt(p.x*p.x+p.y*p.y+p.z*p.z);

}

 

7、判三点共线

int dots_inline(point3 p1,point3 p2,point3p3){

       returnvlen(xmult(subt(p1,p2),subt(p2,p3)))<eps;

}

 

8、判四点共面

int dots_onplane(point3 a,point3 b,point3c,point3 d){

       returnzero(dmult(pvec(a,b,c),subt(d,a)));

}

 

9、判点是否在线段上,包括端点和共线

int dot_online_in(point3 p,line3 l){

       returnzero(vlen(xmult(subt(p,l.a),subt(p,l.b))))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&

              (l.a.y-p.y)*(l.b.y-p.y)<eps&&(l.a.z-p.z)*(l.b.z-p.z)<eps;

}

int dot_online_in(point3 p,point3 l1,point3l2){

       returnzero(vlen(xmult(subt(p,l1),subt(p,l2))))&&(l1.x-p.x)*(l2.x-p.x)<eps&&

              (l1.y-p.y)*(l2.y-p.y)<eps&&(l1.z-p.z)*(l2.z-p.z)<eps;

}

 

10、判点是否在线段上,不包括端点

int dot_online_ex(point3 p,line3 l){

       returndot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y)||!zero(p.z-l.a.z))&&

              (!zero(p.x-l.b.x)||!zero(p.y-l.b.y)||!zero(p.z-l.b.z));

}

int dot_online_ex(point3 p,point3 l1,point3l2){

       returndot_online_in(p,l1,l2)&&(!zero(p.x-l1.x)||!zero(p.y-l1.y)||!zero(p.z-l1.z))&&

              (!zero(p.x-l2.x)||!zero(p.y-l2.y)||!zero(p.z-l2.z));

}

 

11、判点是否在空间三角形上,包括边界,三点共线无意义

int dot_inplane_in(point3 p,plane3 s){

       returnzero(vlen(xmult(subt(s.a,s.b),subt(s.a,s.c)))-vlen(xmult(subt(p,s.a),subt(p,s.b)))-

              vlen(xmult(subt(p,s.b),subt(p,s.c)))-vlen(xmult(subt(p,s.c),subt(p,s.a))));

}

int dot_inplane_in(point3 p,point3s1,point3 s2,point3 s3){

       returnzero(vlen(xmult(subt(s1,s2),subt(s1,s3)))-vlen(xmult(subt(p,s1),subt(p,s2)))-

              vlen(xmult(subt(p,s2),subt(p,s3)))-vlen(xmult(subt(p,s3),subt(p,s1))));

}

 

12、判点是否在空间三角形上,不包括边界,三点共线无意义

int dot_inplane_ex(point3 p,plane3 s){

       returndot_inplane_in(p,s)&&vlen(xmult(subt(p,s.a),subt(p,s.b)))>eps&&

              vlen(xmult(subt(p,s.b),subt(p,s.c)))>eps&&vlen(xmult(subt(p,s.c),subt(p,s.a)))>eps;

}

int dot_inplane_ex(point3 p,point3s1,point3 s2,point3 s3){

       returndot_inplane_in(p,s1,s2,s3)&&vlen(xmult(subt(p,s1),subt(p,s2)))>eps&&

              vlen(xmult(subt(p,s2),subt(p,s3)))>eps&&vlen(xmult(subt(p,s3),subt(p,s1)))>eps;

}

 

13、判两点在线段同侧,点在线段上返回0,不共面无意义

int same_side(point3 p1,point3 p2,line3 l){

       returndmult(xmult(subt(l.a,l.b),subt(p1,l.b)),xmult(subt(l.a,l.b),subt(p2,l.b)))>eps;

}

int same_side(point3 p1,point3 p2,point3l1,point3 l2){

       returndmult(xmult(subt(l1,l2),subt(p1,l2)),xmult(subt(l1,l2),subt(p2,l2)))>eps;

}

 

14、判两点在线段异侧,点在线段上返回0,不共面无意义

int opposite_side(point3 p1,point3 p2,line3l){

       returndmult(xmult(subt(l.a,l.b),subt(p1,l.b)),xmult(subt(l.a,l.b),subt(p2,l.b)))<-eps;

}

int opposite_side(point3 p1,point3p2,point3 l1,point3 l2){

       returndmult(xmult(subt(l1,l2),subt(p1,l2)),xmult(subt(l1,l2),subt(p2,l2)))<-eps;

}

 

15、判两点在平面同侧,点在平面上返回0

int same_side(point3 p1,point3 p2,plane3s){

       returndmult(pvec(s),subt(p1,s.a))*dmult(pvec(s),subt(p2,s.a))>eps;

}

int same_side(point3 p1,point3 p2,point3s1,point3 s2,point3 s3){

       returndmult(pvec(s1,s2,s3),subt(p1,s1))*dmult(pvec(s1,s2,s3),subt(p2,s1))>eps;

}

 

16、判两点在平面异侧,点在平面上返回0

int opposite_side(point3 p1,point3p2,plane3 s){

       returndmult(pvec(s),subt(p1,s.a))*dmult(pvec(s),subt(p2,s.a))<-eps;

}

int opposite_side(point3 p1,point3p2,point3 s1,point3 s2,point3 s3){

       returndmult(pvec(s1,s2,s3),subt(p1,s1))*dmult(pvec(s1,s2,s3),subt(p2,s1))<-eps;

}

 

17、判两直线平行

int parallel(line3 u,line3 v){

       returnvlen(xmult(subt(u.a,u.b),subt(v.a,v.b)))<eps;

}

int parallel(point3 u1,point3 u2,point3v1,point3 v2){

       returnvlen(xmult(subt(u1,u2),subt(v1,v2)))<eps;

}

 

18、判两平面平行

int parallel(plane3 u,plane3 v){

       returnvlen(xmult(pvec(u),pvec(v)))<eps;

}

int parallel(point3 u1,point3 u2,point3u3,point3 v1,point3 v2,point3 v3){

       returnvlen(xmult(pvec(u1,u2,u3),pvec(v1,v2,v3)))<eps;

}

 

19、判直线与平面平行

int parallel(line3 l,plane3 s){

       returnzero(dmult(subt(l.a,l.b),pvec(s)));

}

int parallel(point3 l1,point3 l2,point3s1,point3 s2,point3 s3){

       returnzero(dmult(subt(l1,l2),pvec(s1,s2,s3)));

}

 

20、判两直线垂直

int perpendicular(line3 u,line3 v){

       returnzero(dmult(subt(u.a,u.b),subt(v.a,v.b)));

}

int perpendicular(point3 u1,point3u2,point3 v1,point3 v2){

       returnzero(dmult(subt(u1,u2),subt(v1,v2)));

}

 

21、判两平面垂直

int perpendicular(plane3 u,plane3 v){

       returnzero(dmult(pvec(u),pvec(v)));

}

int perpendicular(point3 u1,point3u2,point3 u3,point3 v1,point3 v2,point3 v3){

       returnzero(dmult(pvec(u1,u2,u3),pvec(v1,v2,v3)));

}

 

22、判直线与平面平行

int perpendicular(line3 l,plane3 s){

       returnvlen(xmult(subt(l.a,l.b),pvec(s)))<eps;

}

int perpendicular(point3 l1,point3l2,point3 s1,point3 s2,point3 s3){

       returnvlen(xmult(subt(l1,l2),pvec(s1,s2,s3)))<eps;

}

 

23、判两线段相交,包括端点和部分重合

int intersect_in(line3 u,line3 v){

       if(!dots_onplane(u.a,u.b,v.a,v.b))

              return 0;

       if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))

              return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);

       returndot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);

}

int intersect_in(point3 u1,point3 u2,point3v1,point3 v2){

       if(!dots_onplane(u1,u2,v1,v2))

              return 0;

       if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2))

              return!same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2);

       returndot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2);

}

 

24、判两线段相交,不包括端点和部分重合

int intersect_ex(line3 u,line3 v){

       returndots_onplane(u.a,u.b,v.a,v.b)&&opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);

}

int intersect_ex(point3 u1,point3 u2,point3v1,point3 v2){

       returndots_onplane(u1,u2,v1,v2)&&opposite_side(u1,u2,v1,v2)&&opposite_side(v1,v2,u1,u2);

}

 

25、判线段与空间三角形相交,包括交于边界和(部分)包含

int intersect_in(line3 l,plane3 s){

       return!same_side(l.a,l.b,s)&&!same_side(s.a,s.b,l.a,l.b,s.c)&&

              !same_side(s.b,s.c,l.a,l.b,s.a)&&!same_side(s.c,s.a,l.a,l.b,s.b);

}

int intersect_in(point3 l1,point3 l2,point3s1,point3 s2,point3 s3){

       return!same_side(l1,l2,s1,s2,s3)&&!same_side(s1,s2,l1,l2,s3)&&

              !same_side(s2,s3,l1,l2,s1)&&!same_side(s3,s1,l1,l2,s2);

}

 

26、判线段与空间三角形相交,不包括交于边界和(部分)包含

int intersect_ex(line3 l,plane3 s){

       returnopposite_side(l.a,l.b,s)&&opposite_side(s.a,s.b,l.a,l.b,s.c)&&

              opposite_side(s.b,s.c,l.a,l.b,s.a)&&opposite_side(s.c,s.a,l.a,l.b,s.b);

}

int intersect_ex(point3 l1,point3 l2,point3s1,point3 s2,point3 s3){

       returnopposite_side(l1,l2,s1,s2,s3)&&opposite_side(s1,s2,l1,l2,s3)&&

              opposite_side(s2,s3,l1,l2,s1)&&opposite_side(s3,s1,l1,l2,s2);

}

 

27、计算两直线交点,注意事先判断直线是否共面和平行!

//线段交点请另外判线段相交(同时还是要判断是否平行!)

point3 intersection(line3 u,line3 v){

       point3ret=u.a;

       doublet=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))

                     /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));

       ret.x+=(u.b.x-u.a.x)*t;

       ret.y+=(u.b.y-u.a.y)*t;

       ret.z+=(u.b.z-u.a.z)*t;

       returnret;

}

point3 intersection(point3 u1,point3u2,point3 v1,point3 v2){

       point3ret=u1;

       doublet=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))

                     /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));

       ret.x+=(u2.x-u1.x)*t;

       ret.y+=(u2.y-u1.y)*t;

       ret.z+=(u2.z-u1.z)*t;

       returnret;

}

 

28、计算直线与平面交点,注意事先判断是否平行,并保证三点不共线!

//线段和空间三角形交点请另外判断

point3 intersection(line3 l,plane3 s){

       point3ret=pvec(s);

       doublet=(ret.x*(s.a.x-l.a.x)+ret.y*(s.a.y-l.a.y)+ret.z*(s.a.z-l.a.z))/

              (ret.x*(l.b.x-l.a.x)+ret.y*(l.b.y-l.a.y)+ret.z*(l.b.z-l.a.z));

       ret.x=l.a.x+(l.b.x-l.a.x)*t;

       ret.y=l.a.y+(l.b.y-l.a.y)*t;

       ret.z=l.a.z+(l.b.z-l.a.z)*t;

       returnret;

}

point3 intersection(point3 l1,point3l2,point3 s1,point3 s2,point3 s3){

       point3ret=pvec(s1,s2,s3);

       doublet=(ret.x*(s1.x-l1.x)+ret.y*(s1.y-l1.y)+ret.z*(s1.z-l1.z))/

              (ret.x*(l2.x-l1.x)+ret.y*(l2.y-l1.y)+ret.z*(l2.z-l1.z));

       ret.x=l1.x+(l2.x-l1.x)*t;

       ret.y=l1.y+(l2.y-l1.y)*t;

       ret.z=l1.z+(l2.z-l1.z)*t;

       returnret;

}

 

29、计算两平面交线,注意事先判断是否平行,并保证三点不共线!

line3 intersection(plane3 u,plane3 v){

       line3ret;

       ret.a=parallel(v.a,v.b,u.a,u.b,u.c)?intersection(v.b,v.c,u.a,u.b,u.c):intersection(v.a,v.b,u.a,u.b,u.c);

       ret.b=parallel(v.c,v.a,u.a,u.b,u.c)?intersection(v.b,v.c,u.a,u.b,u.c):intersection(v.c,v.a,u.a,u.b,u.c);

       returnret;

}

line3 intersection(point3 u1,point3u2,point3 u3,point3 v1,point3 v2,point3 v3){

       line3ret;

       ret.a=parallel(v1,v2,u1,u2,u3)?intersection(v2,v3,u1,u2,u3):intersection(v1,v2,u1,u2,u3);

       ret.b=parallel(v3,v1,u1,u2,u3)?intersection(v2,v3,u1,u2,u3):intersection(v3,v1,u1,u2,u3);

       returnret;

}

 

30、点到直线距离

double ptoline(point3 p,line3 l){

       returnvlen(xmult(subt(p,l.a),subt(l.b,l.a)))/distance(l.a,l.b);

}

double ptoline(point3 p,point3 l1,point3l2){

       returnvlen(xmult(subt(p,l1),subt(l2,l1)))/distance(l1,l2);

}

 

31、点到平面距离

double ptoplane(point3 p,plane3 s){

       returnfabs(dmult(pvec(s),subt(p,s.a)))/vlen(pvec(s));

}

double ptoplane(point3 p,point3 s1,point3s2,point3 s3){

       returnfabs(dmult(pvec(s1,s2,s3),subt(p,s1)))/vlen(pvec(s1,s2,s3));

}

 

32、直线到直线距离

double linetoline(line3 u,line3 v){

       point3n=xmult(subt(u.a,u.b),subt(v.a,v.b));

       returnfabs(dmult(subt(u.a,v.a),n))/vlen(n);

}

double linetoline(point3 u1,point3u2,point3 v1,point3 v2){

       point3n=xmult(subt(u1,u2),subt(v1,v2));

       returnfabs(dmult(subt(u1,v1),n))/vlen(n);

}

 

33、两直线夹角cos值

double angle_cos(line3 u,line3 v){

       returndmult(subt(u.a,u.b),subt(v.a,v.b))/vlen(subt(u.a,u.b))/vlen(subt(v.a,v.b));

}

double angle_cos(point3 u1,point3 u2,point3v1,point3 v2){

       returndmult(subt(u1,u2),subt(v1,v2))/vlen(subt(u1,u2))/vlen(subt(v1,v2));

}

 

34、两平面夹角cos值

double angle_cos(plane3 u,plane3 v){

       returndmult(pvec(u),pvec(v))/vlen(pvec(u))/vlen(pvec(v));

}

double angle_cos(point3 u1,point3 u2,point3u3,point3 v1,point3 v2,point3 v3){

       returndmult(pvec(u1,u2,u3),pvec(v1,v2,v3))/vlen(pvec(u1,u2,u3))/vlen(pvec(v1,v2,v3));

}

 

35、直线平面夹角sin值

double angle_sin(line3 l,plane3 s){

       returndmult(subt(l.a,l.b),pvec(s))/vlen(subt(l.a,l.b))/vlen(pvec(s));

}

double angle_sin(point3 l1,point3 l2,point3s1,point3 s2,point3 s3){

       returndmult(subt(l1,l2),pvec(s1,s2,s3))/vlen(subt(l1,l2))/vlen(pvec(s1,s2,s3));

}

7、网格

#define abs(x) ((x)>0?(x):-(x))

struct point{int x,y;};

 

int gcd(int a,int b){

       returnb?gcd(b,a%b):a;

}

 

1、多边形上的网格点个数

int grid_onedge(int n,point* p){

       inti,ret=0;

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

              ret+=gcd(abs(p[i].x-p[(i+1)%n].x),abs(p[i].y-p[(i+1)%n].y));

       returnret;

}

 

2、多边形内的网格点个数

int grid_inside(int n,point* p){

       inti,ret=0;

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

              ret+=p[(i+1)%n].y*(p[i].x-p[(i+2)%n].x);

       return(abs(ret)-grid_onedge(n,p))/2+1;

}

8、圆

#include <math.h>

#define eps 1e-8

struct point{double x,y;};

 

double xmult(point p1,point p2,point p0){

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

}

 

double distance(point p1,point p2){

       returnsqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));

}

 

double disptoline(point p,point l1,pointl2){

       returnfabs(xmult(p,l1,l2))/distance(l1,l2);

}

 

point intersection(point u1,point u2,pointv1,point v2){

       pointret=u1;

       doublet=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))

                     /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));

       ret.x+=(u2.x-u1.x)*t;

       ret.y+=(u2.y-u1.y)*t;

       returnret;

}

 

1、判直线和圆相交,包括相切

int intersect_line_circle(point c,doubler,point l1,point l2){

       returndisptoline(c,l1,l2)<r+eps;

}

 

2、判线段和圆相交,包括端点和相切

int intersect_seg_circle(point c,doubler,point l1,point l2){

       doublet1=distance(c,l1)-r,t2=distance(c,l2)-r;

       pointt=c;

       if(t1<eps||t2<eps)

              return t1>-eps||t2>-eps;

       t.x+=l1.y-l2.y;

       t.y+=l2.x-l1.x;

       returnxmult(l1,c,t)*xmult(l2,c,t)<eps&&disptoline(c,l1,l2)-r<eps;

}

 

3、判圆和圆相交,包括相切

int intersect_circle_circle(point c1,doubler1,point c2,double r2){

       returndistance(c1,c2)<r1+r2+eps&&distance(c1,c2)>fabs(r1-r2)-eps;

}

 

4、计算圆上到点p最近点,如p与圆心重合,返回p本身

point dot_to_circle(point c,double r,pointp){

       pointu,v;

       if(distance(p,c)<eps)

              return p;

       u.x=c.x+r*fabs(c.x-p.x)/distance(c,p);

       u.y=c.y+r*fabs(c.y-p.y)/distance(c,p)*((c.x-p.x)*(c.y-p.y)<0?-1:1);

       v.x=c.x-r*fabs(c.x-p.x)/distance(c,p);

       v.y=c.y-r*fabs(c.y-p.y)/distance(c,p)*((c.x-p.x)*(c.y-p.y)<0?-1:1);

       returndistance(u,p)<distance(v,p)?u:v;

}

 

5、计算直线与圆的交点,保证直线与圆有交点

//计算线段与圆的交点可用这个函数后判点是否在线段上

void intersection_line_circle(pointc,double r,point l1,point l2,point& p1,point& p2){

       pointp=c;

       doublet;

       p.x+=l1.y-l2.y;

       p.y+=l2.x-l1.x;

       p=intersection(p,c,l1,l2);

       t=sqrt(r*r-distance(p,c)*distance(p,c))/distance(l1,l2);

       p1.x=p.x+(l2.x-l1.x)*t;

       p1.y=p.y+(l2.y-l1.y)*t;

       p2.x=p.x-(l2.x-l1.x)*t;

       p2.y=p.y-(l2.y-l1.y)*t;

}

 

6、计算圆与圆的交点,保证圆与圆有交点,圆心不重合

void intersection_circle_circle(pointc1,double r1,point c2,double r2,point& p1,point& p2){

       pointu,v;

       doublet;

       t=(1+(r1*r1-r2*r2)/distance(c1,c2)/distance(c1,c2))/2;

       u.x=c1.x+(c2.x-c1.x)*t;

       u.y=c1.y+(c2.y-c1.y)*t;

       v.x=u.x+c1.y-c2.y;

       v.y=u.y-c1.x+c2.x;

       intersection_line_circle(c1,r1,u,v,p1,p2);

}

 

十四、数论

1、阶乘最后非0位

//求阶乘最后非零位,复杂度O(nlogn)

//返回该位,n以字符串方式传入

#include <string.h>

#define MAXN 10000

 

int lastdigit(char* buf){

       constint mod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2};

       intlen=strlen(buf),a[MAXN],i,c,ret=1;

       if(len==1)

              return mod[buf[0]-'0'];

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

              a[i]=buf[len-1-i]-'0';

       for(;len;len-=!a[len-1]){

              ret=ret*mod[a[1]%2*10+a[0]]%5;

              for (c=0,i=len-1;i>=0;i--)

                     c=c*10+a[i],a[i]=c/5,c%=5;

       }

       returnret+ret%2*5;

}

2、模线性方程组

#ifdef WIN32

typedef __int64 i64;

#else

typedef long long i64;

#endif

//扩展Euclid求解gcd(a,b)=ax+by

int ext_gcd(int a,int b,int& x,int&y){

       intt,ret;

       if(!b){

              x=1,y=0;

              return a;

       }

       ret=ext_gcd(b,a%b,x,y);

       t=x,x=y,y=t-a/b*y;

       returnret;

}

 

//计算m^a, O(loga), 本身没什么用, 注意这个按位处理的方法:-P

int exponent(int m,int a){

       intret=1;

       for(;a;a>>=1,m*=m)

              if (a&1)

                     ret*=m;

       returnret;

}

 

//计算幂取模a^b mod n, O(logb)

int modular_exponent(int a,int b,int n){//a^b mod n

       intret=1;

       for(;b;b>>=1,a=(int)((i64)a)*a%n)

              if (b&1)

                     ret=(int)((i64)ret)*a%n;

       returnret;

}

 

//求解模线性方程ax=b (mod n)

//返回解的个数,解保存在sol[]中

//要求n>0,解的范围0..n-1

int modular_linear(int a,int b,int n,int*sol){

       intd,e,x,y,i;

       d=ext_gcd(a,n,x,y);

       if(b%d)

              return 0;

       e=(x*(b/d)%n+n)%n;

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

              sol[i]=(e+i*(n/d))%n;

       returnd;

}

 

//求解模线性方程组(中国余数定理)

//  x= b[0] (mod w[0])

//  x= b[1] (mod w[1])

// ...

//  x= b[k-1] (mod w[k-1])

//要求w[i]>0,w[i]与w[j]互质,解的范围1..n,n=w[0]*w[1]*...*w[k-1]

int modular_linear_system(int b[],intw[],int k){

       intd,x,y,a=0,m,n=1,i;

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

              n*=w[i];

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

              m=n/w[i];

              d=ext_gcd(w[i],m,x,y);

              a=(a+y*m*b[i])%n;

       }

       return(a+n)%n;

}

3、素数

//用素数表判定素数,先调用initprime

int plist[10000],pcount=0;

 

int prime(int n){

       inti;

       if((n!=2&&!(n%2))||(n!=3&&!(n%3))||(n!=5&&!(n%5))||(n!=7&&!(n%7)))

              return 0;

       for(i=0;plist[i]*plist[i]<=n;i++)

              if (!(n%plist[i]))

                     return0;

       returnn>1;

}

 

void initprime(){

       inti;

       for(plist[pcount++]=2,i=3;i<50000;i++)

              if (prime(i))

                     plist[pcount++]=i;

}

 

//miller rabin

//判断自然数n是否为素数

//time越高失败概率越低,一般取10到50

#include <stdlib.h>

#ifdef WIN32

typedef __int64 i64;

#else

typedef long long i64;

#endif

 

int modular_exponent(int a,int b,int n){//a^b mod n

       intret;

       for(;b;b>>=1,a=(int)((i64)a)*a%n)

              if (b&1)

                     ret=(int)((i64)ret)*a%n;

       returnret;

}

 

// Carmicheal number:561,41041,825265,321197185

int miller_rabin(int n,int time=10){

       if(n==1||(n!=2&&!(n%2))||(n!=3&&!(n%3))||(n!=5&&!(n%5))||(n!=7&&!(n%7)))

              return 0;

       while(time--)

              if(modular_exponent(((rand()&0x7fff<<16)+rand()&0x7fff+rand()&0x7fff)%(n-1)+1,n-1,n)!=1)

                     return0;

       return1;

}

4、欧拉函数

int gcd(int a,int b){

       returnb?gcd(b,a%b):a;

}

 

inline int lcm(int a,int b){

       returna/gcd(a,b)*b;

}

 

//求1..n-1中与n互质的数的个数

int eular(int n){

       intret=1,i;

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

              if (n%i==0){

                     n/=i,ret*=i-1;

                     while(n%i==0)

                            n/=i,ret*=i;

              }

       if(n>1)

              ret*=n-1;

       returnret;

}

5、返回x的二进制表示中从低到高的第i位

      语法:result=BitAt(int x, int i);

      参数:

      x:十进制 x

      i:要求二进制的第i位

      返回值:返回x的二进制表示中从低到高的第i位

      注意:

       最低位为第一位

      源程序:

       int BitAt(int x, int i)

      {

          return ( x & (1 << (i-1)));

      }

 

6、质因数分解

      语法:result=int reduce(int prime[],int pn,int n,intrest[])

      参数:

      Prime[]:素数表,至少需要达到sqrt(n)

      pn:素数表的元素个数

      N:待分解的数

      Rest:分解结果,按照升序排列

      返回值:分解因子个数

      源程序:

       int reduce(int prime[],int pn,int n,intrest[])

      {

           int i,k=0;

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

           {

               if (n==1) break;

               if (prime[i]*prime[i]>n){rest[k++]=n;break;}

               while(n%prime[i]==0)

               {

                  n/=prime[i];

                  rest[k++]=prime[i];

               }

           }

           return k;

      }

7、幂取模

举例:输出a^n mod m的值

int pow_mod(int a,int n,int m)

{

   if(n==0)

       return 1;

   int x=pow_mod(a,n/2,m);

   long long ans=(long long)x*x%m;

   if(n%2==1)

       ans=ans*a%m;

   return (int)ans;

}

8、求N^N最左面的数

举例:

#include<iostream>

#include<cmath>

using namespace std;

int main()

{

   __int64 cas,b,i,d;

   double a,m,n,c;

   cin>>cas;

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

    {

       cin>>n;

       a=n*log10(n);

       b=(__int64)(a);

       c=a-b;

       d=(__int64)(pow(10,c));

       cout<<d<<endl;

    }

   return 0;

}

9、求Fibonacci的前四位(其实前几位都行)

思路:

以下是大牛的解释:

先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);
假设给出一个数10234432,那么log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7;

log10(1.0234432)
就是log10(10234432)的小数部分.

log10(1.0234432)=0.010063744
10^0.010063744=1.023443198
那么要取几位就很明显了吧~
先取对数(10),然后得到结果的小数部分bit,pow(10.0,bit)以后如果答案还是<1000那么就一直乘10

注意偶先处理了0~20项是为了方便处理~

这题要利用到数列的公式:an=(1/√5) *[((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)


取完对数


log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)

其中f=(sqrt(5.0)+1.0)/2.0;
因为log10(1-((1-√5)/(1+√5))^n)趋近于0
所以可以写成log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0);
最后取其小数部分。

代码:

#include<iostream>

#include<cmath>

#include<cstdio>

using namespace std;

const double s = (sqrt(5.0)+1.0)/2;

int main()

{

   int n,i;

    doublebit;

   int fac[21] = { 0 , 1 };

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

       fac[i] = fac[i-1] + fac [i-2];

   while(cin >> n)

    {

       if(n <= 20) {

           cout << fac[n] << endl;

           continue;

       }

       else{

           bit = -0.5*log(5.0)/log(10.0)+((double)n)*log(s)/log(10.0);//调用公式

           bit = bit - floor(bit); //取小数部分└(^o^)┘

           bit = pow(10.0,bit);

           while(bit < 1000) //要求四位,所以要将小数点右边的数移到左边直到符合要求

                bit = 10.0 * bit;

           cout << (int)bit << endl;

       }

    }

   return 0;

}

 

10、2^14以内的素数

{

       2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,37, 41, 43, 47, 53, 59, 61, 67, 71, \

       73, 79, 83, 89, 97, 101, 103, 107, 109,113, 127, 131, 137, 139, 149, 151, \

       157, 163, 167, 173, 179, 181, 191, 193,197, 199, 211, 223, 227, 229, 233, \

       239, 241, 251, 257, 263, 269, 271, 277,281, 283, 293, 307, 311, 313, 317, \

       331, 337, 347, 349, 353, 359, 367, 373,379, 383, 389, 397, 401, 409, 419, \

       421, 431, 433, 439, 443, 449, 457, 461,463, 467, 479, 487, 491, 499, 503, \

       509, 521, 523, 541, 547, 557, 563, 569,571, 577, 587, 593, 599, 601, 607, \

       613, 617, 619, 631, 641, 643, 647, 653,659, 661, 673, 677, 683, 691, 701, \

       709, 719, 727, 733, 739, 743, 751, 757,761, 769, 773, 787, 797, 809, 811, \

       821, 823, 827, 829, 839, 853, 857, 859,863, 877, 881, 883, 887, 907, 911, \

       919, 929, 937, 941, 947, 953, 967, 971,977, 983, 991, 997, 1009, 1013, 1019, \

       1021, 1031, 1033, 1039, 1049, 1051, 1061,1063, 1069, 1087, 1091, 1093, 1097, \

       1103, 1109, 1117, 1123, 1129, 1151, 1153,1163, 1171, 1181, 1187, 1193, 1201, \

       1213, 1217, 1223, 1229, 1231, 1237, 1249,1259, 1277, 1279, 1283, 1289, 1291, \

       1297, 1301, 1303, 1307, 1319, 1321, 1327,1361, 1367, 1373, 1381, 1399, 1409, \

       1423, 1427, 1429, 1433, 1439, 1447, 1451,1453, 1459, 1471, 1481, 1483, 1487, \

       1489, 1493, 1499, 1511, 1523, 1531, 1543,1549, 1553, 1559, 1567, 1571, 1579, \

       1583, 1597, 1601, 1607, 1609, 1613, 1619,1621, 1627, 1637, 1657, 1663, 1667, \

       1669, 1693, 1697, 1699, 1709, 1721, 1723,1733, 1741, 1747, 1753, 1759, 1777, \

       1783, 1787, 1789, 1801, 1811, 1823, 1831,1847, 1861, 1867, 1871, 1873, 1877, \

       1879, 1889, 1901, 1907, 1913, 1931, 1933,1949, 1951, 1973, 1979, 1987, 1993, \

       1997, 1999, 2003, 2011, 2017, 2027, 2029,2039, 2053, 2063, 2069, 2081, 2083, \

       2087, 2089, 2099, 2111, 2113, 2129, 2131,2137, 2141, 2143, 2153, 2161, 2179, \

       2203, 2207, 2213, 2221, 2237, 2239, 2243,2251, 2267, 2269, 2273, 2281, 2287, \

       2293, 2297, 2309, 2311, 2333, 2339, 2341,2347, 2351, 2357, 2371, 2377, 2381, \

       2383, 2389, 2393, 2399, 2411, 2417, 2423,2437, 2441, 2447, 2459, 2467, 2473, \

       2477, 2503, 2521, 2531, 2539, 2543, 2549,2551, 2557, 2579, 2591, 2593, 2609, \

       2617, 2621, 2633, 2647, 2657, 2659, 2663,2671, 2677, 2683, 2687, 2689, 2693, \

       2699, 2707, 2711, 2713, 2719, 2729, 2731,2741, 2749, 2753, 2767, 2777, 2789, \

       2791, 2797, 2801, 2803, 2819, 2833, 2837,2843, 2851, 2857, 2861, 2879, 2887, \

       2897, 2903, 2909, 2917, 2927, 2939, 2953,2957, 2963, 2969, 2971, 2999, 3001, \

       3011, 3019, 3023, 3037, 3041, 3049, 3061,3067, 3079, 3083, 3089, 3109, 3119, \

       3121, 3137, 3163, 3167, 3169, 3181, 3187,3191, 3203, 3209, 3217, 3221, 3229, \

       3251, 3253, 3257, 3259, 3271, 3299, 3301,3307, 3313, 3319, 3323, 3329, 3331, \

       3343, 3347, 3359, 3361, 3371, 3373, 3389,3391, 3407, 3413, 3433, 3449, 3457, \

       3461, 3463, 3467, 3469, 3491, 3499, 3511,3517, 3527, 3529, 3533, 3539, 3541, \

       3547, 3557, 3559, 3571, 3581, 3583, 3593,3607, 3613, 3617, 3623, 3631, 3637, \

       3643, 3659, 3671, 3673, 3677, 3691, 3697,3701, 3709, 3719, 3727, 3733, 3739, \

       3761, 3767, 3769, 3779, 3793, 3797, 3803,3821, 3823, 3833, 3847, 3851, 3853, \

       3863, 3877, 3881, 3889, 3907, 3911, 3917,3919, 3923, 3929, 3931, 3943, 3947, \

       3967, 3989, 4001, 4003, 4007, 4013, 4019,4021, 4027, 4049, 4051, 4057, 4073, \

       4079, 4091, 4093, 4099, 4111, 4127, 4129,4133, 4139, 4153, 4157, 4159, 4177, \

       4201, 4211, 4217, 4219, 4229, 4231, 4241,4243, 4253, 4259, 4261, 4271, 4273, \

       4283, 4289, 4297, 4327, 4337, 4339, 4349,4357, 4363, 4373, 4391, 4397, 4409, \

       4421, 4423, 4441, 4447, 4451, 4457, 4463,4481, 4483, 4493, 4507, 4513, 4517, \

       4519, 4523, 4547, 4549, 4561, 4567, 4583,4591, 4597, 4603, 4621, 4637, 4639, \

       4643, 4649, 4651, 4657, 4663, 4673, 4679,4691, 4703, 4721, 4723, 4729, 4733, \

       4751, 4759, 4783, 4787, 4789, 4793, 4799,4801, 4813, 4817, 4831, 4861, 4871, \

       4877, 4889, 4903, 4909, 4919, 4931, 4933,4937, 4943, 4951, 4957, 4967, 4969, \

       4973, 4987, 4993, 4999, 5003, 5009, 5011,5021, 5023, 5039, 5051, 5059, 5077, \

       5081, 5087, 5099, 5101, 5107, 5113, 5119,5147, 5153, 5167, 5171, 5179, 5189, \

       5197, 5209, 5227, 5231, 5233, 5237, 5261,5273, 5279, 5281, 5297, 5303, 5309, \

       5323, 5333, 5347, 5351, 5381, 5387, 5393,5399, 5407, 5413, 5417, 5419, 5431, \

       5437, 5441, 5443, 5449, 5471, 5477, 5479,5483, 5501, 5503, 5507, 5519, 5521, \

       5527, 5531, 5557, 5563, 5569, 5573, 5581,5591, 5623, 5639, 5641, 5647, 5651, \

       5653, 5657, 5659, 5669, 5683, 5689, 5693,5701, 5711, 5717, 5737, 5741, 5743, \

       5749, 5779, 5783, 5791, 5801, 5807, 5813,5821, 5827, 5839, 5843, 5849, 5851, \

       5857, 5861, 5867, 5869, 5879, 5881, 5897,5903, 5923, 5927, 5939, 5953, 5981, \

       5987, 6007, 6011, 6029, 6037, 6043, 6047,6053, 6067, 6073, 6079, 6089, 6091, \

       6101, 6113, 6121, 6131, 6133, 6143, 6151,6163, 6173, 6197, 6199, 6203, 6211, \

       6217, 6221, 6229, 6247, 6257, 6263, 6269,6271, 6277, 6287, 6299, 6301, 6311, \

       6317, 6323, 6329, 6337, 6343, 6353, 6359,6361, 6367, 6373, 6379, 6389, 6397, \

       6421, 6427, 6449, 6451, 6469, 6473, 6481,6491, 6521, 6529, 6547, 6551, 6553, \

       6563, 6569, 6571, 6577, 6581, 6599, 6607,6619, 6637, 6653, 6659, 6661, 6673, \

       6679, 6689, 6691, 6701, 6703, 6709, 6719,6733, 6737, 6761, 6763, 6779, 6781, \

       6791, 6793, 6803, 6823, 6827, 6829, 6833,6841, 6857, 6863, 6869, 6871, 6883, \

       6899, 6907, 6911, 6917, 6947, 6949, 6959,6961, 6967, 6971, 6977, 6983, 6991, \

       6997, 7001, 7013, 7019, 7027, 7039, 7043,7057, 7069, 7079, 7103, 7109, 7121, \

       7127, 7129, 7151, 7159, 7177, 7187, 7193,7207, 7211, 7213, 7219, 7229, 7237, \

       7243, 7247, 7253, 7283, 7297, 7307, 7309,7321, 7331, 7333, 7349, 7351, 7369, \

       7393, 7411, 7417, 7433, 7451, 7457, 7459,7477, 7481, 7487, 7489, 7499, 7507, \

       7517, 7523, 7529, 7537, 7541, 7547, 7549,7559, 7561, 7573, 7577, 7583, 7589, \

       7591, 7603, 7607, 7621, 7639, 7643, 7649,7669, 7673, 7681, 7687, 7691, 7699, \

       7703, 7717, 7723, 7727, 7741, 7753, 7757,7759, 7789, 7793, 7817, 7823, 7829, \

       7841, 7853, 7867, 7873, 7877, 7879, 7883,7901, 7907, 7919, 7927, 7933, 7937, \

       7949, 7951, 7963, 7993, 8009, 8011, 8017,8039, 8053, 8059, 8069, 8081, 8087, \

       8089, 8093, 8101, 8111, 8117, 8123, 8147,8161, 8167, 8171, 8179, 8191, 8209, \

       8219, 8221, 8231, 8233, 8237, 8243, 8263,8269, 8273, 8287, 8291, 8293, 8297, \

       8311, 8317, 8329, 8353, 8363, 8369, 8377,8387, 8389, 8419, 8423, 8429, 8431, \

       8443, 8447, 8461, 8467, 8501, 8513, 8521,8527, 8537, 8539, 8543, 8563, 8573, \

       8581, 8597, 8599, 8609, 8623, 8627, 8629,8641, 8647, 8663, 8669, 8677, 8681, \

       8689, 8693, 8699, 8707, 8713, 8719, 8731,8737, 8741, 8747, 8753, 8761, 8779, \

       8783, 8803, 8807, 8819, 8821, 8831, 8837,8839, 8849, 8861, 8863, 8867, 8887, \

       8893, 8923, 8929, 8933, 8941, 8951, 8963,8969, 8971, 8999, 9001, 9007, 9011, \

       9013, 9029, 9041, 9043, 9049, 9059, 9067,9091, 9103, 9109, 9127, 9133, 9137, \

       9151, 9157, 9161, 9173, 9181, 9187, 9199,9203, 9209, 9221, 9227, 9239, 9241, \

       9257, 9277, 9281, 9283, 9293, 9311, 9319,9323, 9337, 9341, 9343, 9349, 9371, \

       9377, 9391, 9397, 9403, 9413, 9419, 9421,9431, 9433, 9437, 9439, 9461, 9463, \

       9467, 9473, 9479, 9491, 9497, 9511, 9521,9533, 9539, 9547, 9551, 9587, 9601, \

       9613, 9619, 9623, 9629, 9631, 9643, 9649,9661, 9677, 9679, 9689, 9697, 9719, \

       9721, 9733, 9739, 9743, 9749, 9767, 9769,9781, 9787, 9791, 9803, 9811, 9817, \

       9829, 9833, 9839, 9851, 9857, 9859, 9871,9883, 9887, 9901, 9907, 9923, 9929, \

       9931, 9941, 9949, 9967, 9973, 10007,10009, 10037, 10039, 10061, 10067, \

       10069, 10079, 10091, 10093, 10099, 10103,10111, 10133, 10139, 10141, 10151, \

       10159, 10163, 10169, 10177, 10181, 10193,10211, 10223, 10243, 10247, 10253, \

       10259, 10267, 10271, 10273, 10289, 10301,10303, 10313, 10321, 10331, 10333, \

       10337, 10343, 10357, 10369, 10391, 10399,10427, 10429, 10433, 10453, 10457, \

       10459, 10463, 10477, 10487, 10499, 10501,10513, 10529, 10531, 10559, 10567, \

       10589, 10597, 10601, 10607, 10613, 10627,10631, 10639, 10651, 10657, 10663, \

       10667, 10687, 10691, 10709, 10711, 10723,10729, 10733, 10739, 10753, 10771, \

       10781, 10789, 10799, 10831, 10837, 10847,10853, 10859, 10861, 10867, 10883, \

       10889, 10891, 10903, 10909, 10937, 10939,10949, 10957, 10973, 10979, 10987, \

       10993, 11003, 11027, 11047, 11057, 11059,11069, 11071, 11083, 11087, 11093, \

       11113, 11117, 11119, 11131, 11149, 11159,11161, 11171, 11173, 11177, 11197, \

       11213, 11239, 11243, 11251, 11257, 11261,11273, 11279, 11287, 11299, 11311, \

       11317, 11321, 11329, 11351, 11353, 11369,11383, 11393, 11399, 11411, 11423, \

       11437, 11443, 11447, 11467, 11471, 11483,11489, 11491, 11497, 11503, 11519, \

       11527, 11549, 11551, 11579, 11587, 11593,11597, 11617, 11621, 11633, 11657, \

       11677, 11681, 11689, 11699, 11701, 11717,11719, 11731, 11743, 11777, 11779, \

       11783, 11789, 11801, 11807, 11813, 11821,11827, 11831, 11833, 11839, 11863, \

       11867, 11887, 11897, 11903, 11909, 11923,11927, 11933, 11939, 11941, 11953, \

       11959, 11969, 11971, 11981, 11987, 12007,12011, 12037, 12041, 12043, 12049, \

       12071, 12073, 12097, 12101, 12107, 12109,12113, 12119, 12143, 12149, 12157, \

       12161, 12163, 12197, 12203, 12211, 12227,12239, 12241, 12251, 12253, 12263, \

       12269, 12277, 12281, 12289, 12301, 12323,12329, 12343, 12347, 12373, 12377, \

       12379, 12391, 12401, 12409, 12413, 12421,12433, 12437, 12451, 12457, 12473, \

       12479, 12487, 12491, 12497, 12503, 12511,12517, 12527, 12539, 12541, 12547, \

       12553, 12569, 12577, 12583, 12589, 12601,12611, 12613, 12619, 12637, 12641, \

       12647, 12653, 12659, 12671, 12689, 12697,12703, 12713, 12721, 12739, 12743, \

       12757, 12763, 12781, 12791, 12799, 12809,12821, 12823, 12829, 12841, 12853, \

       12889, 12893, 12899, 12907, 12911, 12917,12919, 12923, 12941, 12953, 12959, \

       12967, 12973, 12979, 12983, 13001, 13003,13007, 13009, 13033, 13037, 13043, \

       13049, 13063, 13093, 13099, 13103, 13109,13121, 13127, 13147, 13151, 13159, \

       13163, 13171, 13177, 13183, 13187, 13217,13219, 13229, 13241, 13249, 13259, \

       13267, 13291, 13297, 13309, 13313, 13327,13331, 13337, 13339, 13367, 13381, \

       13397, 13399, 13411, 13417, 13421, 13441,13451, 13457, 13463, 13469, 13477, \

       13487, 13499, 13513, 13523, 13537, 13553,13567, 13577, 13591, 13597, 13613, \

       13619, 13627, 13633, 13649, 13669, 13679,13681, 13687, 13691, 13693, 13697, \

       13709, 13711, 13721, 13723, 13729, 13751,13757, 13759, 13763, 13781, 13789, \

       13799, 13807, 13829, 13831, 13841, 13859,13873, 13877, 13879, 13883, 13901, \

       13903, 13907, 13913, 13921, 13931, 13933,13963, 13967, 13997, 13999, 14009, \

       14011, 14029, 14033, 14051, 14057, 14071,14081, 14083, 14087, 14107, 14143, \

       14149, 14153, 14159, 14173, 14177, 14197,14207, 14221, 14243, 14249, 14251, \

       14281, 14293, 14303, 14321, 14323, 14327,14341, 14347, 14369, 14387, 14389, \

       14401, 14407, 14411, 14419, 14423, 14431,14437, 14447, 14449, 14461, 14479, \

       14489, 14503, 14519, 14533, 14537, 14543,14549, 14551, 14557, 14561, 14563, \

       14591, 14593, 14621, 14627, 14629, 14633,14639, 14653, 14657, 14669, 14683, \

       14699, 14713, 14717, 14723, 14731, 14737,14741, 14747, 14753, 14759, 14767, \

       14771, 14779, 14783, 14797, 14813, 14821,14827, 14831, 14843, 14851, 14867, \

       14869, 14879, 14887, 14891, 14897, 14923,14929, 14939, 14947, 14951, 14957, \

       14969, 14983, 15013, 15017, 15031, 15053,15061, 15073, 15077, 15083, 15091, \

       15101, 15107, 15121, 15131, 15137, 15139,15149, 15161, 15173, 15187, 15193, \

       15199, 15217, 15227, 15233, 15241, 15259,15263, 15269, 15271, 15277, 15287, \

       15289, 15299, 15307, 15313, 15319, 15329,15331, 15349, 15359, 15361, 15373, \

       15377, 15383, 15391, 15401, 15413, 15427,15439, 15443, 15451, 15461, 15467, \

       15473, 15493, 15497, 15511, 15527, 15541,15551, 15559, 15569, 15581, 15583, \

       15601, 15607, 15619, 15629, 15641, 15643,15647, 15649, 15661, 15667, 15671, \

       15679, 15683, 15727, 15731, 15733, 15737,15739, 15749, 15761, 15767, 15773, \

       15787, 15791, 15797, 15803, 15809, 15817,15823, 15859, 15877, 15881, 15887, \

       15889, 15901, 15907, 15913, 15919, 15923,15937, 15959, 15971, 15973, 15991, \

       16001, 16007, 16033, 16057, 16061, 16063,16067, 16069, 16073, 16087, 16091, \

       16097, 16103, 16111, 16127, 16139, 16141,16183, 16187, 16189, 16193, 16217, \

       16223, 16229, 16231, 16249, 16253, 16267,16273, 16301, 16319, 16333, 16339, \

       16349, 16361, 16363, 16369, 16381

}

11、求最大公约数,最小公倍数

最大公约数举例:

#include<iostream>

using namespace std;

int gcd(int a,int b)

{

   return b==0?a:gcd(b,a%b);

}

int main()

{

   cout<<gcd(24,36)<<endl;

   return 0;

}

输出结果:

12

 

最小公倍数举例lcm:

#include<iostream>

using namespace std;

int gcd(int a,int b)

{

   return b==0?a:gcd(b,a%b);

}

int lcm(int a,int b)

{

return a/gcd(a,b)*b;

}

int main()

{

   cout<<24/gcd(24,36)*36<<endl;

   return 0;

}

输出结果:

72

 

结论:最小公倍数lcm(a,b)=a/gcd(a,b)*b

12、用N个三角形最多可以把平面分成几个区域?

公式:f(n)=3*n*(n-1)+2

此题重在理解推导公式,f(n)=f(n-1)+6*(n-1),化简为:f(n)=3*n*(n-1)+2。    一个三角形的时候,再加一个三角形,每一条变会与第一个三角形的两条边相交,这样增加2个小三角形,即两个面。f(2)=3*2+f(1),再加一个三角形,每一条边会与前两个三角形的四条边相交,形成四个小三角形,f(3)=3*4+f(2),依次类推,即f(n)=3*2*(n-1)+f(n-1)。

13、循环小数换成分数

小数化分数分成两类。 一类:纯循环小数化分数,循环节做分子;连写几个九作分母,循环节有几位写几个九。例:0.33循环)=3/9(循环节的位数有一个,所以写一个9 0.347347循环)=347/9993位循环节写39 另一类:混循环小数化分数,小数部分减去不循环的数字作分子;连写几个9再紧接着连写几个0作分母,循环节是几个数就写几个9,不循环(小数部分)的数是几个就写几个0。例0.213434循环)=2134-21/9900 

 

 

十五、日期

//日期函数

 

intdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};

struct date{

       intyear,month,day;

};

 

1、判闰年

inline int leap(int year){

       return(year%4==0&&year%100!=0)||year%400==0;

}

 

2、判合法性

inline int legal(date a){

       if(a.month<0||a.month>12)

              return 0;

       if(a.month==2)

              returna.day>0&&a.day<=28+leap(a.year);

       returna.day>0&&a.day<=days[a.month-1];

}

 

3、比较日期大小

inline int datecmp(date a,date b){

   if(a.year!=b.year)

          return a.year-b.year;

   if(a.month!=b.month)

          return a.month-b.month;

  return a.day-b.day;

}

 

4、返回指定日期是星期几

int weekday(date a){

       inttm=a.month>=3?(a.month-2):(a.month+10);

       intty=a.month>=3?a.year:(a.year-1);

       return(ty+ty/4-ty/100+ty/400+(int)(2.6*tm-0.2)+a.day)%7;

}

 

5、日期转天数偏移

int date2int(date a){

       intret=a.year*365+(a.year-1)/4-(a.year-1)/100+(a.year-1)/400,i;

       days[1]+=leap(a.year);

       for(i=0;i<a.month-1;ret+=days[i++]);

       days[1]=28;

       returnret+a.day;

}

 

6、天数偏移转日期

date int2date(int a){

       dateret;

       ret.year=a/146097*400;

       for(a%=146097;a>=365+leap(ret.year);a-=365+leap(ret.year),ret.year++);

       days[1]+=leap(ret.year);

       for(ret.month=1;a>=days[ret.month-1];a-=days[ret.month-1],ret.month++);

       days[1]=28;

       ret.day=a+1;

       returnret;

}

 

0 0
原创粉丝点击