数学问题
这几天看看王道机试的书,觉得几种方法特别有意义,总结如下。
1、数位拆解
问题:特殊的乘法
采用字符数组去转化与分析
如:123 * 45 = 1*4+1*5+2*4+2*5+3*4+3*5
输入:
123 45
输出:
54
#include<stdio.h> int main(){ char buf1[20],buf2[20]; while(scanf("%s %s",buf1,buf2)!=EOF){ int sum=0; for(int i=0;buf1[i]!=0;i++) for(int j=0;buf2[j]!=0;j++) sum+=(buf1[i]-'0')*(buf2[j]-'0'); printf("%d\n",sum); } return 0; }
2、求最大公约数
其原理:若a,b全为0,则他们的最大公约数不存在;若a,b其中之一为0,则最大公约数为他们中最大的不为0的数;若a,b都不为0,则令a=b,而b=a%b(a为前置条件中的a,不是取等之后的数),之后重复该过程。
#include<stdio.h> #include<string.h> int gcd(int a,int b){ if(b==0) return a; else return gcd(b,a%b); } int main() { int a,b; while(scanf("%d%d",&a,&b)!=EOF){ printf("%d\n",gcd(a,b)); } return 0; }
3、数制转换
问题:将一种进制数转化为另一种进制的数
用字符串接受输入的a进制数str,先将其转化为十进制,后转化为b进制,这个过程中要巧用字符数组
#include<stdio.h> #include<string.h> int main(){ int a,b; char str[40]; while(scanf("%d%s%d",&a,str,&b)!=EOF){ int tmp=0,len=strlen(str); int x,c=1; for(int i=len-1 ; i>=0 ; i--){ if(str[i]>='0' && str[i]<='9') x=str[i]-'0'; else if(str[i]>='a' && str[i]<='z') x=str[i]-'a'+10; else x=str[i]-'A'+10; tmp+=x*c; c*=a; } char ans[40],size=0; while(tmp!=0){ int x=tmp%b; ans[size++]=(x<10) ? x+'0':x+'A'-10; tmp/=b; } for(i=size-1;i>=0;i--) printf("%c",ans[i]); printf("\n"); } return 0; }
4、最小公倍数
a,b的最小公倍数的值即为a*b与a,b的最大约数相除
#include<stdio.h> int gcd(int a,int b){ if(b==0) return a; else return gcd(b,a%b); } int main(){ int a,b; while(scanf("%d%d",&a,&b)!=EOF){ printf("%d\n",a*b/gcd(a,b)); } return 0; }
5、大整数问题
可以借助数组以及结构还有c++里的运算的重载实现其运算,编写重载过程要细心。
// bigInteger.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include<stdio.h> #include<string.h> struct bigInt{ int digit[1001]; int size; void init(){ for (int i = 0; i <= 1000; i++){ digit[i] = 0; } size = 0; } void set(char str[]){ init(); int len = strlen(str); for (int i = len - 1, j = 1, c = 1, s = 0; i >= 0; i--, j++){ s += c * ( str[ i ] - '0'); c = c * 10; if (j == 4 || i == 0){ digit[size++] = s; j = 1; s = 0; c = 1; } } } void output(){ for (int i = size-1; i >= 0; i-- ) { if (i == size - 1){ printf("%d", digit[i]); //输出格式,最高位不用考虑 } else printf("%04d", digit[i]); //考虑运算结果不足4位 } printf("\n"); } bigInt operator + (const bigInt A){ bigInt ret; ret.init(); int carry = 0; //carry表示进位 for (int i = 0; i < size || i < A.size; i++){ int tmp = digit[i] + A.digit[i] + carry; carry = tmp / 10000; ret.digit[ret.size++] = tmp % 10000; } if (carry != 0){ ret.digit[ret.size++] = carry; } return ret; } }; int main() { char xs[20], ys[20]; bigInt xb, yb; while (scanf("%s %s", xs, ys) != EOF){ xb.set(xs); yb.set(ys); xb = xb + yb; xb.output(); } return 0; }
很希望自己是一棵树,守静、向光、安然,敏感的神经末梢,触着流云和微风,窃窃的欢喜。脚下踩着最卑贱的泥,很踏实。还有,每一天都在隐秘成长。