最大公约数
int gcd(int a, int b){ // a % b = c .... r if(b == 0) return a; else return gcd(b, a % b); //b, r }
最小公倍数: a、b的最大公约数是c,则a、b的最小公倍数是a / c * b。
分数运算
1、表示:struct frac{ int up, down }, 运算以假分数形式进行, 输出时再化为代分数。乘除法时,分子分母使用长整数保存。
2、化简: 化简在每一次计算完后进行,先检查分母,若分母小于0,应分子分母同*-1, 若分母等于0,应将 inf 标志置为1; 然后分子分母同除最大公因数(计算时应传入绝对值,求两个绝对值的最大公因数); 两个int分母相乘,有可能溢出,所以分子分母应使用long long保存;
3、输出时考虑:INF标志; 分子为0时直接输出0;分子>=分母时(用绝对值比较),可以整除则输出整数,否则输出代分数(4/1直接输出4);
素数
1、判断素数, 注意下面注释的三个易错点。
int isPrime(int N){ int sqr = (int)sqrt(N * 1.0); //N应该转换为小数 if(N == 1) //当N = 1时应返回false,容易忽略,1不是素数 return 0; for(int i = 2; i <= sqr; i++){ //i <= sqr; i从2开始查找 if(N % i == 0) return 0; } return 1; }
2、筛法求N以内素数表:num[] 数组标记一个数是不是素数。初始2标记为素数。然后从2开始遍历直到N,如果i是素数, 那就把它在N以内的所有倍数都标记为非素数。
超长整数计算
1、大整数的记录结构:
typedef struct info{ int num[100]; int len; info(){ for(int i = 0; i < 100; i++){ //全初始化为0,这样在做加法时可以直接循环到最长的数,而不是仅仅循环到最短的数就结束。 num[i] = 0; } len = 0; } }bign;
2、大整数加法:
bign add(bign a, bign b){ int carry = 0; bign c; for(int i = 0; i < a.len || i < b.len; i++){ //以长的数位界 int temp = a.num[i] + b.num[i] + carry; c.num[i] = temp % 10; carry = temp / 10; c.len++; } if(carry != 0) c.num[c.len++] = carry; return c; }
3、大整数乘法: 注意最后乘完每一位之后,carry有可能>=10,需要不止1位存储。 注意正负号问题。