题目1491:求1和2的个数
时间限制:1 秒
内存限制:128 兆
特殊判题:否
提交:1286
解决:382
-
题目描述:
-
给定正整数N,函数F(N)表示小于等于N的自然数中1和2的个数之和,例如:1,2,3,4,5,6,7,8,9,10序列中1和2的个数之和为3,因此F(10)=3。输入N,求F(N)的值,1=<N<=10^100(10的100次方)若F(N)很大,则求F(N)mod20123的值。
-
————————————————————分割线—————————————————————————
-
思路参考《编程之美》P135
-
思想大概是:对于一个数abcde
-
对于c来讲,先分析c这个位置出现1的次数,c位置出现1的次数主要是靠两个部分决定的,分别是【ab】和【de】这两个数字,
-
当c==1时,c位置出现1的次数 = de+1+ab*100
-
c>1时候, c位置出现1的次数 = ab*100+100;
-
c ==0时候 ,c位置出现1的次数 =ab*100;
-
100就是c位置所代表的位数(也就是百位)
-
需要注意的是,MOD的数要在每次计算时候都要模上
-
-
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; const int MOD = 20123; char s[1005]; int pow(int n) { int an = 0; int t = 1; for(int i = n ;i>=0;i--) { an += (s[i]-'0')*t; an %=MOD; t*=10; t%=MOD; } return an; } int dp(int n) { int an = 0; int t = 1; for(int i = strlen(s)-1 ;i>=n;i--) { an += (s[i]-'0')*t; an %=MOD; t*=10; t%=MOD; } return an; } int p(int n) { int an=1; while(n--) { an*=10; an%=MOD; } return an; } int main() { while(~scanf("%s",s)) { long long ans = 0; int n,d; d = 0; for(int i = strlen(s)-1 ; i >= 0;i--) { int tmp = pow(i-1); // cout<<tmp<<endl; n=s[i]-'0'; if(n==1) { ans += dp(i+1)+1; ans += tmp*p(strlen(s)-i-1); } else { ans += tmp*p(strlen(s)-i-1); if(n>1) ans+=p(strlen(s)-i-1); } if(n==2) { ans += dp(i+1)+1; ans += tmp*p(strlen(s)-i-1); } else { ans += tmp*p(strlen(s)-i-1); if(n>2) ans+=p(strlen(s)-i-1); } d = n; ans %=MOD; //cout<<strlen(s)-i<<" "<<ans<<endl; } cout<<ans%MOD<<endl; } }
-