ZJNU 2340/2341/2343 - 罗小黑的“礼物”Ⅰ/Ⅱ/Ⅲ
Posted stelayuri
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZJNU 2340/2341/2343 - 罗小黑的“礼物”Ⅰ/Ⅱ/Ⅲ相关的知识,希望对你有一定的参考价值。
把一位数、两位数、三位数……这些所在的范围分开判断
可得1~9这些数范围在[1,9]内
10~99内共有90个数,每个数占两位,所以共有180位在,范围在[10,189]内
同理,100~999内共有900个数,每个数占三位,所以共有2700位在,范围在[190,2889]内
……
最后对于范围,可以得出一个规律
9 189 2889 38889 488889 ......
知道了范围,就可以求指定的答案了
比如输入一个数n范围在[190,2889]内
就能知道这是个三位数
n-190后,0/1/2对应数字100的三位,3/4/5对应数字101的三位,以此类推
所以(n-190)/3+100可以找出对应的数字
而(n-190)%3可以找出是对应的数字的第几位
(代码中写成(n-189+2)/3+99,意思相同,2代表位数减1)
因此对于Ⅰ题,可以直接暴力敲代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int q,n,d,dd; 5 cin>>q; 6 while(q--){ 7 cin>>n; 8 if(n<=9) 9 cout<<n<<endl; 10 else if(n>9&&n<=189){ 11 d=(n-9+1)/2+9; 12 if(n&1) 13 cout<<d%10<<endl; 14 else 15 cout<<d/10<<endl; 16 } 17 else if(n>189&&n<=2889){ 18 d=(n-189+2)/3+99; 19 dd=(n-189)%3; 20 if(dd==0) 21 cout<<d%10<<endl; 22 else if(dd==1) 23 cout<<d/100<<endl; 24 else 25 cout<<d/10%10<<endl; 26 } 27 else{ 28 d=(n-2889+3)/4+999; 29 dd=(n-2889)%4; 30 if(dd==0) 31 cout<<d%10<<endl; 32 else if(dd==1) 33 cout<<d/1000<<endl; 34 else if(dd==2) 35 cout<<d/100%10<<endl; 36 else 37 cout<<d/10%10<<endl; 38 } 39 } 40 41 return 0; 42 }
对于Ⅱ,这种方法显然可行(我真闲……)
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int q,n,d,dd; 5 cin>>q; 6 while(q--){ 7 cin>>n; 8 if(n<=9) 9 cout<<n<<endl; 10 else if(n>9&&n<=189){ 11 d=(n-9+1)/2+9; 12 if(n&1) 13 cout<<d%10<<endl; 14 else 15 cout<<d/10<<endl; 16 } 17 else if(n>189&&n<=2889){ 18 d=(n-189+2)/3+99; 19 dd=(n-189)%3; 20 if(dd==0) 21 cout<<d%10<<endl; 22 else if(dd==1) 23 cout<<d/100<<endl; 24 else 25 cout<<d/10%10<<endl; 26 } 27 else if(n>2889&&n<=38889){ 28 d=(n-2889+3)/4+999; 29 dd=(n-2889)%4; 30 if(dd==0) 31 cout<<d%10<<endl; 32 else if(dd==1) 33 cout<<d/1000<<endl; 34 else if(dd==2) 35 cout<<d/100%10<<endl; 36 else 37 cout<<d/10%10<<endl; 38 } 39 else{ 40 d=(n-38889+4)/5+9999; 41 dd=(n-38889)%5; 42 if(dd==0) 43 cout<<d%10<<endl; 44 else if(dd==1) 45 cout<<d/10000<<endl; 46 else if(dd==2) 47 cout<<d/1000%10<<endl; 48 else if(dd==3) 49 cout<<d/100%10<<endl; 50 else 51 cout<<d/10%10<<endl; 52 } 53 } 54 55 return 0; 56 }
但是对于Ⅲ,1e18的范围让原本开开心心的我懵了
但是都找出规律得出解法了还能怎么办
数据打个表用循环做!
以下代码三道题目均能使用
1 #include<stdio.h> 2 int main(){ 3 long long q,n,d,dd,i,j,qq[16]={9LL,189LL,2889LL,38889LL,488889LL,5888889LL,68888889LL,788888889LL,8888888889LL,98888888889LL,1088888888889LL,11888888888889LL,128888888888889LL,1388888888888889LL,14888888888888889LL,158888888888888889LL},qd[17]={9LL,99LL,999LL,9999LL,99999LL,999999LL,9999999LL,99999999LL,999999999LL,9999999999LL,99999999999LL,999999999999LL,9999999999999LL,99999999999999LL,999999999999999LL,9999999999999999LL},ed[18]={1LL,10LL,100LL,1000LL,10000LL,100000LL,1000000LL,10000000LL,100000000LL,1000000000LL,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL}; 4 scanf("%lld",&q); 5 while(q--){ 6 scanf("%lld",&n); 7 if(n<=9) 8 printf("%lld ",n); 9 else{ 10 for(i=0;i<=15;i++){ 11 if(i<15&&n>qq[i]&&n<=qq[i+1]||i==15&&n>qq[15]){ 12 d=(n-qq[i]+i+1)/(i+2)+qd[i]; 13 dd=(n-qq[i])%(i+2); 14 if(dd==0) 15 printf("%lld ",d%10); 16 for(j=1;j<i+2;j++){ 17 if(dd==j){ 18 printf("%lld ",d/ed[i+2-j]%10); 19 break; 20 } 21 } 22 break; 23 } 24 } 25 } 26 } 27 28 return 0; 29 }
完美!(
以上是关于ZJNU 2340/2341/2343 - 罗小黑的“礼物”Ⅰ/Ⅱ/Ⅲ的主要内容,如果未能解决你的问题,请参考以下文章