九度OJ 1491 清华大学2012机试 《求1和2的个数》
2015-02-09 17:22
183 查看
给定正整数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
看了一份别人的代码,十分简略,不明白怎么做的,就发到了论坛里,有人给讲解了,讲得很棒
比如输入12345,那么先算F(1),再由F(1)算出F(12),依次再算出F(123),F(1234),F(12345);
主要计算的就是rslt=(rslt-cnt)*10+num*2+cnt*(t+1)+min(t,2);这一句了。
rslt是结果;num是实际输入的数;cnt是num这个数中1,2的数量;
首先认为已经算出了F(12)=rslt,需要算F(123)
1.显然12变成了12X的形式,所以原来1-11中每一个数都可以加上一个个位(因为不知道个位是不是9,所以最后一个12不能乘10,以后单独计算),而个位是从0-9,所以原来的每个数都有10中变化,而最后一个数12的1,2的数量为cnt,所以有(rslt-cnt)*10,;
(比如比12小的有1,2的数是:1,2,10,11,扩大十倍后,有10-19,20-29,100-109,110-119,每个数各对应十个数,他们原本的的1和2被加了十次,所以乘以10)
2.上一步中余有一个12没有计算,显然12X这个数的个位只能是0-3,所以有cnt*(t+1);
(t是X位的数,cnt是12的1,2个数,为2,t从0开始,所以是cnt*(t+1)个)
3.上面的计算中都没有考虑对个位为1,2的计数,00-11中个位为1,2的显然是每10个数中有2个,所以有num*2
4.12X个位的1,2个数,直接判断就好了,min(t,2);
输入:
输入包含多组测试数据,每组仅输入一个整数N。
输出:
对于每组测试数据,输出小于等于N的自然数中1和2的个数之和,且对20123取模。
样例输入:
10
11
样例输出:
3
5
看了一份别人的代码,十分简略,不明白怎么做的,就发到了论坛里,有人给讲解了,讲得很棒
比如输入12345,那么先算F(1),再由F(1)算出F(12),依次再算出F(123),F(1234),F(12345);
主要计算的就是rslt=(rslt-cnt)*10+num*2+cnt*(t+1)+min(t,2);这一句了。
rslt是结果;num是实际输入的数;cnt是num这个数中1,2的数量;
首先认为已经算出了F(12)=rslt,需要算F(123)
1.显然12变成了12X的形式,所以原来1-11中每一个数都可以加上一个个位(因为不知道个位是不是9,所以最后一个12不能乘10,以后单独计算),而个位是从0-9,所以原来的每个数都有10中变化,而最后一个数12的1,2的数量为cnt,所以有(rslt-cnt)*10,;
(比如比12小的有1,2的数是:1,2,10,11,扩大十倍后,有10-19,20-29,100-109,110-119,每个数各对应十个数,他们原本的的1和2被加了十次,所以乘以10)
2.上一步中余有一个12没有计算,显然12X这个数的个位只能是0-3,所以有cnt*(t+1);
(t是X位的数,cnt是12的1,2个数,为2,t从0开始,所以是cnt*(t+1)个)
3.上面的计算中都没有考虑对个位为1,2的计数,00-11中个位为1,2的显然是每10个数中有2个,所以有num*2
4.12X个位的1,2个数,直接判断就好了,min(t,2);
#include <stdio h=""> #include <string h=""> #include <iostream> using namespace std; int main() { char N[110] = {0}; while(cin>>N) { int i,t = 0; int result,num,cnt; //result是结果,num是当前计算的N,cnt即num这个数中的1,2个数 result = num = cnt = 0; int len = strlen(N); for(i = 0; i < len; i++) { t = N[i] - '0'; result = (result - cnt)*10 + cnt*(t+1) + num*2 + min(t,2); num = num*10 + t; if(t == 1 || t == 2) cnt++; num %= 20123; result %= 20123; } printf("%d\n",result); } return 0; } </iostream></string></stdio>
相关文章推荐
- 九度OJ 1482 清华大学2012机试 《玛雅人的秘密》
- 九度OJ 1085 清华大学2010机试《求root(N,k)》
- 九度OJ 1082 清华大学2009年机试
- 【九度OJ】1490【字符串链接】【C实现】【哈工大2012】
- 【九度OJ】1465【最大公约数】【C实现】【北大2012】
- 九度OJ 1107 搬水果 -- 哈夫曼树 2011年吉林大学计算机研究生机试真题
- 【九度OJ】1489【矩阵乘法】【C实现】【哈工大2012】
- 九度题目1088:剩下的树 2011年清华大学计算机研究生机试真题
- 九度OJ 1086 动态规划之《最小花费》——11年清华机试真题
- 【九度OJ】1480【动态规划】【C实现】【北大2012】
- 九度 oj 题目1491:求1和2的个数
- 华为机试—寻找丑数 && 九度OJ 1214
- 九度OJ题目1491:求1和2的个数
- 【九度OJ】1484【模拟】【C实现】【北大2012】
- 九度OJ 1491-1500(5/10)
- 九度OJ题目1491:求1和2的个数
- 九度OJ 1019 简单计算器 -- 2006年浙江大学计算机及软件工程研究生机试真题
- 九度OJ-浙大机试-题目1437:To Fill or Not to Fill
- 【九度OJ】1485【密码】【C实现】【北大2012】
- 九度OJ 1019 简单计算器 -- 2006年浙江大学计算机及软件工程研究生机试真题