The lucky numbers--Southeastern European Regional Programming Contest Bucharest, Romania 2009

The Lucky Numbers 
Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB
Total submit users: 1, Accepted users: 1
Problem 10806 : No special judgement
Problem description
  John and Brus are freshmen at the primary school. Their first home task is to learn some integer numbers. It is not so hard for the guys and they decide to impress their teacher by learning all lucky numbers between A and B, inclusive.
As you already know from the previous year contest 4 and 7 are lucky digits, and all the other digits are not lucky. A lucky number is a number that contains only lucky digits in decimal notation.
After learning all lucky numbers in [A, B] range John and Brus still have some free time and now they decide to learn additionally each lucky number N that is out of [A, B] range, but the reversed number of N is in this range. Here reversed number of N is the number N written in decimal notation, but the order of digits is reversed. For example, the reversed number of 447 is 744 and reversed number of 774474444 is 444474477.
You are given integers A and B and your task is to find the total number of lucky numbers learned by John and Brus.

Input
  The first line contains single integer T ? the number of test cases. Each test case consists of a single line containing two integers A and B separated by a single space.

 

Constraints:

1 ≤ T ≤ 74,
1 ≤ A ≤ B ≤ 100000000000000000000000000000000000000000000000 (1047).


Output
  For each test case print a single line containing the total number of lucky numbers learned by John and Brus.

Sample Input
2 
1 100 
44 47
Sample Output
6 
3

 

http://acm.hunnu.edu.cn/online/?action=problem&type=show&id=10806

http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=2759 这个好像又不能进了

 

  题目大意:只包含4和7的数字称为幸运数字,给你A和B,求出在AB之间或者翻转后在AB之间的幸运数个数。

  思路:一个半小时;实现:2个小时;改BUG:5个小时。结论:55555,在比赛中我不可能AC的啊!!!

 

  这么大的数字完全不用考虑暴力啊。于是各种草稿,发现了一个不错的方法,总之我是要搞个函数f(num),得出翻转前后都小于等于num的数字的个数,由这个函数及其略微变形我可以求出翻转前后都比A小的,翻转前后都比B大的,翻转前比A小、翻转后比B大的,翻转后比A小、翻转前比B大的,总数减去这些就是答案了。

 

  其实我是先想到这个函数的大概构架再想到思路的。这函数怎么写呢?先找到翻转前必小于等于原数的数,然后找出这些数里翻转后必小于等于原数的数(=。=|||这是废话么?不是吧。。。)。比如4747,从左到右扫描到一个7,把它变成4,那么44XX必是比原数小的,把它翻转XX44,由于原数在XX的位置是47,不比47大的数有两个44、47,可得出44开头的数有两个是翻转前后都比4747小的。然后又扫描到一个7,变成4744,翻转4474,它比4747小,也是一个。刚才找的都是小于4747的,4747本身不符合条件,不用加1。这样就得出翻转前后都比4747小的数有3个。当然这只是大概思路,还有好多细节,比如7744,扫描到第二个7变成74XX,翻转后是XX47,按刚才说法该有4(77->44 47 74 77)种,但由于47>44,所以其中相等的一种情况(77)要减去,7747>7744,而其他依然是满足条件的。还有个注意的就是找完所有必小于原数的数后还要考虑本身是不是翻转后也小于等于自身,这个也考虑进去这个函数就差不多完整了。

 

  由于我这个函数是求小于等于的,先要把A减1,然后要把AB都转变成不大于自己的最大的幸运数A'B'。这个范围里的幸运数跟原来AB间的幸运数个数一样的。然后用那函数求出翻转前后小于等于A'的个数。那大于B'的呢?长度比B'小的肯定翻转前后都小于它了,长度比它大的不需要考虑,那长度一样的里面呢,根据容斥定理,答案=总数-翻转前小于等于B'的个数-翻转后小于等于B'的个数+翻转前后都小于等于B'的个数。最后呢要求翻转前比A小、翻转后比B大的,显然,这个的个数和翻转后比A小、翻转前比B大的个数是相等的。如果写出了上面那个函数,就会发现略微变下形就可以求出这个了。然后就可以A了啦~~~~~~

 

  感觉这题很考验考虑问题的周到程度,各种细节各种bug,不知道过个半年做这种题目能不能快点。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值