从前我很怕大数运算,每次做到都是头疼的。现在反而没那么怕了,因为只要理解了它的结构和算法模板,就也没那么难了,这算是进步吧hhhh。
不过,有了进步还要更近一步!
第一次的训练里面有三道大题分别是:
Big Number HDU-1212
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11439 Accepted Submission(s): 7645
Problem Description
As we know, Big Number is always troublesome. But it's really important in our ACM. And today, your task is to write a program to calculate A mod B.
To make the problem easier, I promise that B will be smaller than 100000.
Is it too hard? No, I work it out in 10 minutes, and my program contains less than 25 lines.
To make the problem easier, I promise that B will be smaller than 100000.
Is it too hard? No, I work it out in 10 minutes, and my program contains less than 25 lines.
是一道简单的模板题,只要理解用C++数组储存的时候需要将数组倒过来储存,注意进位即可。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <math.h> 6 7 using namespace std; 8 9 int main(){ 10 int n,m; 11 char a[1005]; 12 while(~scanf("%s",a)){ 13 scanf("%d",&n); 14 m=strlen(a); 15 int ans=0; 16 for(int i=0;i<m;i++){ 17 ans=(ans*10+(a[i]-'0'))%n; 18 } 19 printf("%d\n",ans); 20 } 21 return 0; 22 }
A的很快的一道模板水题,接下来这个就要稍微麻烦一些。
第二道:
大明A+B HDU-1212
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 16930 Accepted Submission(s): 6306
Problem Description
话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。
这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。
现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。
这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。
现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。
我用了四个数组来储存,分别储存的是两个实数的整数部分和小数部分,不过要注意的是,我对于两个储存小数部分的数组储存顺序与储存整数部分不同,这是为了方便进位。
所以,这个只要在a+b的情况上多注意些细节就可以了。
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <math.h> 6 7 using namespace std; 8 9 int a1[405],b1[405],a2[405],b2[405]; 10 char s1[405],s2[405]; 11 12 int main(){ 13 int t1,t2,lena,lenb,i,k,num1,num2; 14 while(~scanf("%s%s",s1,s2)){ 15 memset(a1,0,sizeof(a1)); 16 memset(b1,0,sizeof(b1)); 17 memset(a2,0,sizeof(a2)); 18 memset(b2,0,sizeof(b2)); 19 t1=lena=strlen(s1); 20 t2=lenb=strlen(s2); 21 for(int i=0;i<lena;i++){ 22 if(s1[i]=='.'){ 23 t1=i; 24 break; 25 } 26 } 27 for(k=0,i=t1-1;i>=0;i--){ 28 a1[k++]=s1[i]-'0'; 29 } 30 for(k=1,i=t1+1;i<lena;i++){ 31 a2[k++]=s1[i]-'0'; 32 } 33 for(int i=0;i<lenb;i++){ 34 if(s2[i]=='.'){ 35 t2=i; 36 break; 37 } 38 } 39 for(k=0,i=t2-1;i>=0;i--){ 40 b1[k++]=s2[i]-'0'; 41 } 42 for(k=1,i=t2+1;i<lenb;i++){ 43 b2[k++]=s2[i]-'0'; 44 } 45 num1=(lena-t1)>(lenb-t2)?(lena-t1):(lenb-t2); 46 for(i=num1;i>=1;i--){ 47 a2[i]+=b2[i]; 48 if(a2[i]>=10){ 49 a2[i]-=10; 50 a2[i-1]+=1; 51 } 52 } 53 num2=(t1-1)>(t2-1)?t1-1:t2-1; 54 a1[0]+=a2[0]; 55 for(i=0;i<=num2;i++){ 56 a1[i]+=b1[i]; 57 if(a1[i]>=10){ 58 a1[i]-=10; 59 a1[i+1]+=1; 60 } 61 } 62 if(a1[num2+1]>0) 63 printf("%d",a1[num2+1]); 64 for(i=num2;i>=0;i--) 65 printf("%d",a1[i]); 66 for(i=num1;i>=1;i--) 67 { 68 if(a2[i]==0) 69 continue; 70 else 71 break; 72 } 73 if(i==0) 74 {} 75 else 76 { 77 printf("."); 78 for(int j=1;j<=i;j++) 79 printf("%d",a2[j]); 80 } 81 printf("\n"); 82 } 83 return 0; 84 }
代码比较长,这个是我的方法,期待能用上更简便的方法来解决这道题。
最后是第三题:emmm这个其实不是大数题,就是很简单的用int 直接进行加减运算就可以A的水题,但是我当时真的想都没想就开始大数操作,结果就WA了。
A + B Problem
Problem Description
Calculate A + B.
接着WA了以后考虑,是不还有可能是大数中的负数相加?负数和正数相加?下面贴出我的多想代码hhh
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <math.h> 6 7 using namespace std; 8 9 int main(){ 10 int lena,lenb; 11 char a[1005]={0},b[1005]={0}; 12 while(~scanf("%s%s",a,b)){ 13 int A[1005]={0},B[1005]={0}; 14 lena=strlen(a); 15 lenb=strlen(b); 16 int i,k; 17 if(a[0]=='-'&&b[0]=='-'){ 18 //printf("a[0]=='-'&&b[0]=='-'\n"); 19 for(k=0,i=lena-1;i>0;i--){ 20 A[k++]=a[i]-'0'; 21 } 22 for(k=0,i=lenb-1;i>0;i--){ 23 B[k++]=b[i]-'0'; 24 } 25 k=lena>lenb?lena-1:lenb-1; 26 for(i=0;i<k;i++){ 27 A[i]+=B[i]; 28 if(A[i]>=10){ 29 A[i]-=10; 30 A[i+1]+=1; 31 } 32 } 33 //printf("%d\n",k); 34 printf("-"); 35 if(A[k]==0){ 36 // printf("$55$\n"); 37 for(i=k-1;i>=0;i--){ 38 printf("%d",A[i]); 39 } 40 } 41 else{ 42 //printf("$$\n"); 43 for(i=k;i>=0;i--){ 44 printf("%d",A[i]); 45 } 46 } 47 printf("\n"); 48 continue; 49 } 50 if(a[0]=='-'&&b[0]!='-'){ //a小于0,b大于0 51 for(k=0,i=lena-1;i>0;i--){ 52 A[k++]=a[i]-'0'; 53 } 54 for(k=0,i=lenb-1;i>=0;i--){ 55 B[k++]=b[i]-'0'; 56 } 57 k=lena-1>lenb?lena-1:lenb; 58 if(k==lena-1){ 59 60 } 61 for(i=0;i<k;i++){ 62 A[i]+=B[i]; 63 if(A[i]>=10){ 64 A[i]-=10; 65 A[i+1]+=1; 66 } 67 } 68 //printf("%d\n",k); 69 printf("-"); 70 if(A[k]==0){ 71 // printf("$55$\n"); 72 for(i=k-1;i>=0;i--){ 73 printf("%d",A[i]); 74 } 75 } 76 else{ 77 //printf("$$\n"); 78 for(i=k;i>=0;i--){ 79 printf("%d",A[i]); 80 } 81 } 82 printf("\n"); 83 continue; 84 } 85 //两个数都大于0 86 for(k=0,i=lena-1;i>=0;i--){ 87 A[k++]=a[i]-'0'; 88 } 89 for(k=0,i=lenb-1;i>=0;i--){ 90 B[k++]=b[i]-'0'; 91 } 92 k=lena>lenb?lena:lenb; 93 for(i=0;i<k;i++){ 94 A[i]+=B[i]; 95 if(A[i]>=10){ 96 A[i]-=10; 97 A[i+1]+=1; 98 } 99 } 100 //printf("%d\n",k); 101 if(A[k]==0){ 102 for(i=k-1;i>=0;i--){ 103 printf("%d",A[i]); 104 } 105 } 106 else{ 107 for(i=k;i>=0;i--){ 108 printf("%d",A[i]); 109 } 110 } 111 printf("\n"); 112 } 113 return 0; 114 }
然后还有大数的阶乘,大数相减的一些练习,不过我现在还没有做到大数相除,不知道大数相除会是什么亚子的。