题目连接: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 }
时间: 2024-08-28 09:38:31