題意:給定一個整數n,給定一個整數k,將1~n個整數按字典順序進行排序,返回排序后第k個元素。
題目鏈接:HDU6468
多組輸入,T<=100,n<=1e6
分析:這個題和之前做的模擬出棧的性質挺像的,不是你將1-n個數字排好序或者直接算出第k個數時誰,而是模擬題意的炒作,一步步填充,填充到第k個元素結束
可以分成兩步來做,首先求出以1,2......9開頭的數且小於n的數總共有多少個,並且每算出一個就用k-數目,如果到了某個數不夠減了,說明我們要求的那個數就是一這個數開頭的,跳出循環。
第二步,一點點來,具體實現就直接看代碼吧
我自己寫還是錯了很多次才最終寫對
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf=1<<30; const int maxn=6007; const double pi=acos(-1); const int mod=1e9+7; int ans=0,n,k; //用來得到比n小,以i為開頭的數的數目 int getnum(int n,int i){ int base=1,sum=0; while(n>=(base*(i+1))){ sum+=base; base*=10; } if(n>=(base*i))sum+=n-base*i+1; return sum; } void getans(int &cnt,int cul){ if(++cnt==k){ ans=cul; return ; } for(int i=0;i<=9;i++){//注意,這里是從0開始了 int t=cul*10+i; if(t<=n) getans(cnt,t); if(cnt>=k) return ;//保證有這一步免得程序重復執行 } } int main(){ int T;scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); int i;//注意i不要在for循環里定義 for(i=1;i<=9;i++){ int num=getnum(n,i); if(k>num) k-=num; else break; } int cnt=0; getans(cnt,i); cout<<ans<<endl; } return 0; }