Find the nth digit(二分查找) - HDU 1597

Posted ACM算法日常

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Find the nth digit(二分查找) - HDU 1597相关的知识,希望对你有一定的参考价值。

拜个晚年~祝各位2018新年快乐!狗年旺旺!


Problem Description

假设:

S1 = 1

S2 = 12

S3 = 123

S4 = 1234

.........

S9 = 123456789

S10 = 1234567891

S11 = 12345678912

............

S18 = 123456789123456789

..................

现在我们把所有的串连接起来

S = 1121231234.......123456789123456789112345678912.........

那么你能告诉我在S串中的第N个数字是多少吗?

 

Input

输入首先是一个数字K,代表有K次询问。

接下来的K行每行有一个整数N(1 <= N < 2^31)。

 

Output

对于每个N,输出S中第N个对应的数字.

 

Sample Input

6

1

2

3

4

5

10

 

Sample Output

1

1

2

1

2

4


题意容易理解,但是做到高效需要注意二分查找的写法。


关于二分检索:

        二分检索的思想是每次把范围缩小一半。例如,你需要在一个从小到大有 序的有15个元素的线性表中查找数11 ,而已知第8个数是“6”,“11”如果在 表中,那么它一定在第9个数〜第15个数这个范围之内。


解题说明:

        本题只是使用常规的二分查找,由于没有使用递归,性能会好很多。本题最关键的地方在于使用了一张表保存所有的位置信息,进而进行区间划分,使得后面能够使用二分查找解题。


源码:G++ 0ms

#include <stdio.h>

int main()
{
   //静态存储区默认值为0,66000是调整的值,只要不WA,可以尝试从大往小调
   static int sum[66000];
   int index;
   int position;
   //初始化表,这张表记录了每个区间的位置
   //0,1(0+1),3(1+2),6(3+3)...
   for (int i = 1; i < 66000; ++i) {
       sum[i] = sum[i - 1] + i;
   }

   int count;
   scanf("%d", &count);

   while (count--) {
       scanf("%d", &position);
       index = -1;
       int l = 1;
       int r = 66000;
       //二分查找
       while (1) {
           //每次进来算出新的中间位置
           int mid = (l + r) / 2;
           //正好在区间里面,注意这里是index=mid
           if (sum[mid] < position && sum[mid + 1] >= position) {
               index = mid;
               break;
           }
           //如果在左区间,则将r指针指向中间
           if (position <= sum[mid])
               r = mid - 1;
           //如果在右区间,则将l指针指向中间
           if (sum[mid + 1] < position)
               l = mid + 1;
       }
       //n为位置,减去区间值,则是剩余的值,如101,如果区间值为90
       //则剩余11,这个11代表的肯定是12345678912这样的串
       int value = position - sum[index];
       //取余,去掉1-9这样的重复串
       value %= 9;
       if (value == 0) {
           value = 9;
       }
       printf("%d\n", value);
   }
}


以上是关于Find the nth digit(二分查找) - HDU 1597的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode400. Nth Digit

400. Nth Digit

400. Nth Digit

nth-digit

[LeetCode] Nth Digit

400. Nth digit