题目地址:http://ac.jobdu.com/problem.php?pid=1491
时间限制:1 秒内存限制:128 兆特殊判题:否提交:697解决:199
题目描述:
给定正整数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()!
来源:
2013年王道论坛研究生机试练习赛(三)
【解题思路】
这个题目分析起来和题目1373:整数中1出现的次数(从1到n整数中1出现的次数)完全一样
具体分析过程可以参考【九度】题目1373:整数中1出现的次数(从1到n整数中1出现的次数)
不同之处在于处理字符串,给出具体的代码实现。
Java AC
import java.util.Scanner; public class Main { /* * 1491 */ private static int mod = 20123; private static char array[]; private static int len; public static void main(String[] args) throws Exception { Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { String input = scanner.next(); array = input.toCharArray(); len = array.length; System.out.println(modValue(calCount(1) + calCount(2))); } } private static int calCount(int num) { int k = len - 1; int factor = 1; int count = 0; while (k >= 0) { int lowNum = 0; int currNum = 0; int highNum = 0; for (int i = 0; i < k; i++) { highNum = modValue(modValue(highNum * 10) + (array[i] - '0')); } for (int i = k+1; i < len; i++) { lowNum = modValue(modValue(lowNum * 10) + array[i] - '0'); } currNum = array[k] - '0'; if (currNum < num){ count = modValue(count + highNum * factor); }else if (currNum == num) { count = modValue(count + highNum * factor + lowNum + 1); }else if (currNum > num) { count = modValue(count + (highNum + 1) * factor); } factor = modValue(factor * 10); k--; } return count; } private static int modValue(int n) { return n % mod; } } /************************************************************** Problem: 1491 User: wzqwsrf Language: Java Result: Accepted Time:130 ms Memory:18248 kb ****************************************************************/
C++ AC
#include <stdio.h> #include <string.h> const int mod = 20123; int len; int i; char array[1000]; int modValue(int n){ return n % mod; } int calCount(int num) { int k = len - 1; int factor = 1; int count = 0; while (k >= 0) { int lowNum = 0; int currNum = 0; int highNum = 0; for (i = 0; i < k; i++) { highNum = modValue(modValue(highNum * 10) + (array[i] - '0')); } for (i = k+1; i < len; i++) { lowNum = modValue(modValue(lowNum * 10) + array[i] - '0'); } currNum = array[k] - '0'; if (currNum < num){ count = modValue(count + highNum * factor); }else if (currNum == num) { count = modValue(count + highNum * factor + lowNum + 1); }else if (currNum > num) { count = modValue(count + (highNum + 1) * factor); } factor = modValue(factor * 10); k--; } return count; } int main(){ while(scanf("%s",&array) != EOF){ len = strlen(array); printf("%d\n",modValue(calCount(1) + calCount(2))); } return 0; } /************************************************************** Problem: 1491 User: wzqwsrf Language: C++ Result: Accepted Time:10 ms Memory:1020 kb ****************************************************************/