NYOJ 105
九的余数
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
-
现在给你一个自然数n,它的位数小于等于一百万,现在你要做的就是求出这个数整除九之后的余数。
- 输入
- 第一行有一个整数m(1<=m<=8),表示有m组测试数据;
随后m行每行有一个自然数n。 - 输出
- 输出n整除九之后的余数,每次输出占一行。
- 样例输入
-
3 4 5 465456541
- 样例输出
-
4 5 4
解答:
-
首先本题的思路首先可以发现如果直接取余是不可行的,因为后面的数有几百万位的,纵使long double 也远远不够。这时候就需要考虑如何解决“大数对9取余”这个问题。我们发现,a=an*10n+an-1*10n-1+...+a2*102+a1*101+a0 . a%9 = (an*10n+an-1*10n-1+...+a2*102+a1*101 )%9 = (an*10n)%9+(an-1*10n-1)%9...+(a2*102)%9+(a1*101)%9 + a0%9 = (an%9)*(10n%9) +(an-1%9)*(10n-1%9)+...+(a2%9)*(102%9)+(a1%9)*(101%9).+a0%9 = (an%9)*1 +(an-1%9)*1+......+(a2%9)*1+(a1%9)*1+a0%9 = (an+an-1+...+a2+a1+a0)%9.
即“这个数的各个位上的数字的和”对9取余即得结果。
首先代码如下:
1 2 #include <iostream> 3 #include <stdlib.h> 4 using namespace std; 5 6 int main(){ 7 int m; 8 cin>>m; 9 while(m--){ 10 string n;cin>>n; 11 int res = 0; 12 while(n.length()!=0){ 13 string temp = n.substr(0,1); 14 res += atoi( temp.c_str() ); 15 n = n.substr( 1,n.length()-1 ); 16 } 17 18 cout<<res%9<<endl; 19 } 20 21 }
结果是TimeLimitExceeded 。
遂改进,得如下代码:
1 #include<iostream> 2 #include<vector> 3 #include<string> 4 #include<cstring> 5 6 using namespace std; 7 8 vector<int>a; 9 int DIV(string m)//分切数并存储 10 { 11 int num=m.size();//存储数的长度 12 for(int i=0;i<num;i++){ 13 a.push_back(m[i]-'0'); 14 } 15 return num; 16 } 17 18 int main(){ 19 int M; 20 cin>>M; 21 while(M--){ 22 string n;//存储输入的数 23 cin>>n; 24 long num=DIV(n); 25 long sum=0; 26 27 for(int i=0;i<num;i++){ 28 sum+=a[i]; 29 } 30 cout<<sum%9<<endl; 31 a.clear(); 32 } 33 return 0; 34 }
终AC,可以发现,对于string的substr()操作是比较费时的,甚至比压入vector的时间还长。这是优化代码的一个方向。
-