题目描述:
给定正整数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的值。
输入:
输入包含多组测试数据,每组仅输入一个整数N。
输出:
对于每组测试数据,输出小于等于N的自然数中1和2的个数之和,且对20123取模。
样例输入:
10
11
样例输出:
3
5
提示:
建议用scanf ("%s")输入,而不建议用gets()!
说明:10^100次方很大,计算机基本类型保存不了,需要做特别的保存及加法,下面的代码没有实现,只是实现的怎么求1和2的个数的逻辑
已经花了我很长时间了,改天有时间再写个大数据的加法功能
里面插了个正常计算的方法比对结果
代码如下:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> /* *说明:使用循环判断输入数的低位到高位 *如输入234 *先判断4 -> 得1和2的个数为2 *再判断3 -> 包括(31,32)(20~29)(10~19)(1,2) 共26个 等于 (3-2+1) + 10^1 + 10^1 + 2 根据当前位是0是1还是2还是其他区别开 *再判断2 -> ... * ... *另外:如果数字是n个9,比如999,的1和2的和为k * 则(n+1)个9,如9999,所求的和为(9-2)*k + 10^n + 10^n + k * */ //初始化输入数字串 ,输入 0<=n<=10^100 ,所以建立一个128大小的字符数组保存 char numStr[128] = {0}; //int result[128] = {0}; //保存结果 //int nine[128] = {0}; //保存全部是9的数字的求出的1和2的总和 int re=0; //保存结果 int fre=0; //保存上一次求和结果 int nine=0; //保存全部是9的数字的1和2的总和 int cnum=0; //当前位右侧子串大小 int num=0; //当前位数值 int digit=0; //循环到当前第几位 //void big_add(); //大数据加法 未实现 int normal_count(char*); //正常计算的方法 void main(){ int len; int i=0; int normalsum=0; //保存正常计算的变量 //获取输入数字 scanf("%s",&numStr); //printf(" :%s ",numStr); len = strlen(numStr); normalsum = normal_count(numStr); printf("正常思路计算时1和2结果:%d ",normalsum); for(i=len-1;i>=0;i--,digit++){ num = (int)numStr[i] - 48; if(num < 0 || num > 10){ printf("输入非数字 "); } switch(num){ case 0: break; case 1: if(digit == 0){ re = 1; }else{ re = cnum + 1 + nine; } break; case 2: if(digit==0){ re = 2; }else{ re = cnum + 1 + nine + (int)pow(10,digit); } break; default: if(digit==0){ re = 2; }else{ re = fre + (num-2)*nine + 2 * (int)pow(10,digit); } } /* 计算全9以下1和2数字的总和 */ if(digit == 0){ nine = 2; }else{ nine *= 8; nine += 2 * (int)pow(10,digit); } //子串大小 cnum += num * (int)pow(10,digit); //设置上次求和为本次 fre = re; } printf(" 您输入的数字共出现1和2的次数为:%d次。 ",re); system("pause"); } /* 使用正常方式计算 */ int normal_count(char* set){ int len; int i,j; int s; int num; int sum=0; len = strlen(set); for(i=len-1;i>=0;i--){ s = (int)set[i] -48; if(i == len-1){ num = s; }else{ num += s * (int)pow(10,len-i-1); } } for(j=0;j<=num;j++){ int x=0; int c=j; while(c != 0){ x= c%10; c = c/10; if(x == 1 || x == 2){ sum++; break; } } } return sum; }