在ACM竞赛中,经常可以看到数学问题的身影,可以是纯数学问题,也可以是需要利用数学上的一些公式,定理,算法来辅助解决的问题。会者不难,而不会的选手在赛场上一般很难推出公式或进行证明,往往想起来费劲,写起来却很轻松。
数论
组合数学
博弈论
线性代数
高等数学
线性规划
概率统计
...
简而言之,数论就是研究整数的理论,在ACM竞赛中,经常用到数论的相关知识。纯数论的题目不多,大部分是和其他类型的问题结合起来的。约数,倍数,模线性方程,欧拉定理,素数。
第一部分:同余相关
整除的性质->欧几里德算法
->扩展欧几里德算法->中国剩余定理
第二部分:素数相关
算术基本定理->欧拉定理
->素数测试-> Pollard rho方法
基本概念:
1、素数合数
如果大于1的正整数p仅有的正因子是1和p, 则称p为素数(prime)。
大于1又不是素数的正整数称为合数(compound),如果n是合数, 则n必有一个小于或等于n1/2的素因子。
2、算数基本定理
·····每个正整数都可以惟一地表示成素数的乘积,其中素数因子从小到大依次出现(这里的“乘积”可以有0个、1个或多个素因子)。
·····换句话说, 任意正整数n可以写成n=2a1*3a2*5a3*…,其中a1,a2,a3等为非负整数
·····这个定理也叫做惟一分解定理。它是一个定理而不是公理!虽然在大多人看来,它是“显然成立”的,但它的确是需要证明的定理
3、除法和同余
---令a为整数,d为正整数,那么有惟一的整数q和r,其中0≤r<d,使得a=dq+r
---可以用这个定理来定义除法:d叫除数,a叫被除数,q叫商,r叫余数。如果两个数a,b除以一个数c的余数相等,说a和b关于模c同余,记作a≡b(mod c)
余数 | 0(7) | 1 | 2 | 3 | 4 | 5 | 6 |
排列 | 3241 | 1324 | 1234 | 2341 | 1243 | 1342 | 2134 |
/***** 简单数论题目 ********/ /******** written by C_Shit_Hu ************/ ////////////////数论/////////////// /****************************************************************************/ /* 把数字1,2,3,4从中各抽出1个,然后把其他数字按原顺序(其实任一顺序都可以)排列,组成自然数w。 w×10000模7有7种可能,即是0,1,2,3,4,5,6,这时若能用数字1,2,3,4排列出7个数, 使它们整除7取余的值分别为0,1,2,3,4,5,6。则把这个4位数接在w后面即为原问题的解。 */ /****************************************************************************/ #include <stdlib.h> #include <stdio.h> #include <iostream.h> int main() { int data; scanf("%d",&data);//读取输入数据 /**找出1,2,3,4组合中对7取余数分别为0,6,5,4,3,2,1,情况*/ int add[7]={3241,2134,2413,1243,2341,1234,1324}; int temp1=0; int temp2=0; bool flat[4]={false,false,false,false};//用于标记抽取到数字1,2,3,4的情况,即是验证输入数据是否符合要求 /*以下循环把数字1,2,3,4从中抽取出来,然后其他数字按照原输入数据的逆序排成自然数*/ while(data!=0) { temp1 = data%10;//抽取末位数字 data = data/10;//去掉末位数字,向右移 if((temp1==1 || temp1==2 || temp1==3 || temp1==4)&&(!flat[temp1-1])) { flat[temp1-1]=true; } else { temp2 =temp2*10 + temp1;//如果不是数字1234则按照原输入数据的逆序排成自然数 } } if(flat[0]&&flat[1]&&flat[2]&&flat[3])//判断输入数据是否合理 { data=temp2*10000; //为后面的加运算腾出末四位数 temp2=data%7; //求余 if(temp2==0) //根据求出的余数加上由1,2,3,4组成的四位数 { data = data+3241; } else if(temp2 ==6) { data = data+2134; } else if(temp2 ==5) { data = data+2413; } else if(temp2 ==4) { data = data+1243; } else if(temp2 ==3) { data = data+2341; } else if(temp2 ==2) { data = data+1234; } else if(temp2 ==1) { data = data+1324; } printf("%d\n",data);//输出符合要求的结果 } else { printf("the input is illegal\n"); } return 0; } /******************** 心得体会 **********************/ /* 分析数据的关键部分在拆分数字部分 */
运行结果:
【未完待续】。。。。