find the nth digit(二分查找)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1597

find the nth digit

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9517    Accepted Submission(s): 2757


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
 

 

Author
8600
题解:可以用二分解,也可以用二次方程公式解,要注意使用long long
二分查找的代码:
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 using namespace std;
 5 #define ll long long 
 6 ll f(ll x)
 7 {
 8     ll ans = x*(x+1)/2 ;
 9     return ans;
10 }
11 int main()
12 {
13     int T;
14     scanf("%d",&T);
15     for(int i = 0;i < T ;i++)
16     {
17         ll n ;
18         scanf("%lld",&n);
19         if(n==1)
20         {
21             puts("1");
22             continue;
23         }
24         ll l = 1;
25         ll r = n;
26         ll mid =( l+r )/2;
27         int tm = 0;
28         while(r-l>1)
29         {
30             if( f(mid) < n )
31             {
32                 l = mid;
33                 mid = (l+r)/2;
34             }
35             else if( f(mid) > n)
36             {
37                 r = mid;
38                 mid = (l+r)/2;
39             }
40             else if( f(mid)==n )
41             {
42                 tm = mid;
43                 break;
44             }
45         }
46         if(tm!=0)
47         {
48             if(tm%9==0) puts("9");
49             else 
50             printf("%d\n",tm%9);
51         }
52         else 
53         {
54             ll flag = l;
55             ll tt = flag*(flag+1)/2;
56             int sum = n-tt;    
57             if(sum%9==0) puts("9");
58             else 
59             printf("%d\n",sum%9);
60         }
61     }
62     return 0;
63 }

公式代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 using namespace std;
 4 #define ll long long
 5 #define eps 1e-8
 6 
 7 int main()
 8 {
 9     int T;
10     scanf("%d",&T);
11     for(int i =0 ;i < T;i++)
12     {
13         double n;
14         scanf("%lf",&n);
15         double m =(sqrt(1+8*n)-1)/2;
16         ll mm =m;
17         ll tm = mm*(mm+1)/2;
18         ll flag = n-tm;
19         if(flag == 0){if(mm%9==0)printf("9\n");else   printf("%lld\n",mm%9);}
20         else
21         {
22             if(flag%9==0) printf("9\n");
23             else 
24             printf("%lld\n",flag%9);
25         }
26     }
27     return 0 ;
28 }

 

posted on 2015-08-10 16:02  若流芳千古  阅读(351)  评论(0编辑  收藏  举报

导航