zoukankan      html  css  js  c++  java
  • 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)

    因此对于Ⅰ题,可以直接暴力敲代码

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        int q,n,d,dd;
        cin>>q;
        while(q--){
            cin>>n;
            if(n<=9)
                cout<<n<<endl;
            else if(n>9&&n<=189){
                d=(n-9+1)/2+9;
                if(n&1)
                    cout<<d%10<<endl;
                else
                    cout<<d/10<<endl;
            }
            else if(n>189&&n<=2889){
                d=(n-189+2)/3+99;
                dd=(n-189)%3;
                if(dd==0)
                    cout<<d%10<<endl;
                else if(dd==1)
                    cout<<d/100<<endl;
                else
                    cout<<d/10%10<<endl;
            }
            else{
                d=(n-2889+3)/4+999;
                dd=(n-2889)%4;
                if(dd==0)
                    cout<<d%10<<endl;
                else if(dd==1)
                    cout<<d/1000<<endl;
                else if(dd==2)
                    cout<<d/100%10<<endl;
                else
                    cout<<d/10%10<<endl;
            }
        }
        
        return 0;
    }

    对于Ⅱ,这种方法显然也可行

    #include<bits/stdc++.h>
    using namespace std;
    int main(){
        int q,n,d,dd;
        cin>>q;
        while(q--){
            cin>>n;
            if(n<=9)
                cout<<n<<endl;
            else if(n>9&&n<=189){
                d=(n-9+1)/2+9;
                if(n&1)
                    cout<<d%10<<endl;
                else
                    cout<<d/10<<endl;
            }
            else if(n>189&&n<=2889){
                d=(n-189+2)/3+99;
                dd=(n-189)%3;
                if(dd==0)
                    cout<<d%10<<endl;
                else if(dd==1)
                    cout<<d/100<<endl;
                else
                    cout<<d/10%10<<endl;
            }
            else if(n>2889&&n<=38889){
                d=(n-2889+3)/4+999;
                dd=(n-2889)%4;
                if(dd==0)
                    cout<<d%10<<endl;
                else if(dd==1)
                    cout<<d/1000<<endl;
                else if(dd==2)
                    cout<<d/100%10<<endl;
                else
                    cout<<d/10%10<<endl;
            }
            else{
                d=(n-38889+4)/5+9999;
                dd=(n-38889)%5;
                if(dd==0)
                    cout<<d%10<<endl;
                else if(dd==1)
                    cout<<d/10000<<endl;
                else if(dd==2)
                    cout<<d/1000%10<<endl;
                else if(dd==3)
                    cout<<d/100%10<<endl;
                else
                    cout<<d/10%10<<endl;
            }
        }
        
        return 0;
    }

    但是对于Ⅲ,1e18的范围就只能循环找规律了

    数据打个表用循环做!

    以下代码三道题目均能使用

    #include<stdio.h>
    int main(){
        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};
        scanf("%lld",&q);
        while(q--){
            scanf("%lld",&n);
            if(n<=9)
                printf("%lld
    ",n);
            else{
                for(i=0;i<=15;i++){
                    if(i<15&&n>qq[i]&&n<=qq[i+1]||i==15&&n>qq[15]){
                        d=(n-qq[i]+i+1)/(i+2)+qd[i];
                        dd=(n-qq[i])%(i+2);
                        if(dd==0)
                            printf("%lld
    ",d%10);
                        for(j=1;j<i+2;j++){
                            if(dd==j){
                                printf("%lld
    ",d/ed[i+2-j]%10);
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        }
        
        return 0;
    }

    完美!(

  • 相关阅读:
    Tree Grafting
    敌兵布阵
    畅通工程(并查集)
    The Suspects(并查集)
    Ubiquitous Religions(friends变形)
    Friends(采用树结构的非线性表编程)
    小球下落(二叉树)
    铁轨
    卡片游戏
    征服C指针
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12238810.html
Copyright © 2011-2022 走看看