题目地址: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
****************************************************************/