【Chapter08】UVA 10706

链接:戳我

用了快一个小时才弄出来呢。还是不够熟练。

我的解法是这样的:

1. 首先建造两个array

  第一个num[]:用来存1~n这串数字的digit的数量

  第二个total[]:用来存1121231234....n这串数字的digit的数量

  方法:

    1) num[i] = num[i-1] + digits_of_number(i)

    2) total[i] = total[i-1] + num[i]

2. 然后在获得一个target之后:

  用Binary Search在total[]这个array里面找到一个index k,使得:

    total[k-1] < target <= total[k]

  于是我们就知道了query属于哪一个1~k的数字串了。接着,再用Binary Search在num[]里面寻找到另一个index: q,使得:

    num[q-1] < target-total[k-1] <= num[q]

  于是我们就知道了我们要找的这个位置是属于哪个数字的digit了。比如说:k = 11, target-total[k-1] = 11:

    1 2 3 4 5 6 7 8 9 1 0 1 1,从上面的算法我们得到q = 10

    所以我们确定下来,是数字“10”的某个digit。

3. 得到上面的信息之后,用query-total[k-1]-num[q-1],我们就能得到query指向的index是q这个数字的第(i+1)th index。有i+1是因为,这样的运算是把ditgit的排列看成从1th开始的。

 

 1 import math
 2 
 3 # num[n] = the number of digits in 1~n
 4 # s[n] = the number of digits from 1~n: 112123123412345.....digits(n)
 5 def digit_sum(n):
 6     num = [0]
 7     for i in range(1,n):
 8         num.append(num[i-1] + len(str(i)))
 9 
10     s = [0]
11     for i in range(1, n):
12         s.append(s[i-1] + num[i])
13 
14     return num, s
15 
16 
17 def binary_search(target, array, lower, upper):
18     hit = -1
19     while lower < upper:
20         mid = lower + (upper-lower)/2
21 
22         if array[mid] == target:
23             hit = mid
24             break
25         elif array[mid] < target:
26             hit = mid + 1
27             lower = mid + 1
28         else:
29             hit = mid
30             upper = mid
31 
32     return hit
33 
34 def main():
35     n = 31463
36     num, total = digit_sum(n)
37 
38     with open('10706.txt', 'r') as ins:
39         count = int(ins.readline().strip())
40 
41         for i in range(count):
42             target = int(ins.readline().strip())
43             index_in_total = binary_search(target, total, 0, n)
44             rest = target - total[index_in_total-1]
45             index_in_num = binary_search(rest, num, 0, n)
46             index = rest - num[index_in_num-1]
47 
48             print str(index_in_num)[index-1]
49 
50 if __name__ == "__main__":
51     main()

 

 

posted @ 2013-07-25 15:19  frankdj  阅读(195)  评论(0编辑  收藏  举报