这题我中午是12点以后开始做的,只剩下1个小时了,12点50的时候完成了框架,但是细节总是实现不对,现在晚上来复盘的时候才把这题A出来了。
但是,就像高考的导数你整个思路都会,你死在了求导上。。。(刚才A出来的那一刻真的快把我气哭了哈哈哈哈哈哈还不如不做出来呢)

题面

分析
众所周知,蓝桥杯是数学杯。所以这题有没有什么数学方法来求解呢?
我们不妨先观察一下10-100的数据,一共有5*9个:
10 12 14 16 18
21 23 25 27 29
30
41
50
61
70
81
90
100-1000
101 103 105 107 109
121
141
161
181
210 212 214 216 218230
250
270
290
一直到900多,合计5*5*9个。
同理,1000-10000的区间,5*5*5*9个。那么就有规律了
现在我们回头用数学知识解释一下,第一位是1-9,但是接下来的每一个都只能选5个,因为不是奇数就是偶数。
那么,我们可以先通过n定位到ans的数量级。具体做法就是定义一个区间数组,落在哪里,数量级就能通过它定下来。
定下了数量级,那么我们是不是还可以进一步缩小范围,确定它的第一位?具体实现就是确定出这一位,我们设为hhh(但是实际上是hhh+1)
接下来我们再用一个循环,从左到右依次确定每一小位。
为什么第一位要单独拎出来呢?就是因为第一位可以选9个数,但是后面的数都根据前一位数的奇偶性来判定。
我们用一个例子来说明我的代码:n=716
716推出pos=2,那么npos=3,ans=1000,leave=716-270=446。(此时确定ans数量级是1000)
hhh=446/125=3,leave=446%125=71,那么ans=1000+3*1000=4000(具体确定出第一位)
然后进入循环
1.fst=4,npos=2,hhh=71/25=2,leave=71%25=21,ans=4000+2*hhh*pow(10,npos)=4400
但是第二位和第一位撞了,所以需要加100避开,ans=4500
2.fst=5,npos=1,hhh=21/5=4,leave=21%5=1,ans=4500+2*hhh*pow(10,nops)=4580
第三位不用改变
3.fst=8,npos=0,hhh=4/1=4,leave=0,ans=4580+2*hhh*pow(10,npos)=4582
第四位需要+pow(10,pos),ans=4583.
循环结束
但是,我们验证这个例子,n=716应该对应4581!除此之外,n=1时ans=12,n=11时n=32。
这就是我中午死掉的地方。
我们n自减1就行了。
我中午没想出来,一直在改循环,现在也不知道改没改对,能对几个,反正,,,我做好15分全死的准备了,心痛www
Code
代码功底比较烂,有很多变量名设置需要大家自己理解!求包容。
cpp
#include<iostream>
#include<cmath>
#define mx 1000000007
using namespace std;
long long qujian[25]={0};
long long n;
int main()
{
qujian[1]=45;
for(int i=2;i<=16;i++){
qujian[i]=qujian[i-1]+9*pow(5,i);
}
cin>>n;
n-=1;
long long pos=0;
for(int i=0;i<=20;i++){
if(n>qujian[i]&&n<=qujian[i+1]){
pos=i;
break;
}
}
//cout<<pos<<endl;
long long leave=n-qujian[pos];
long long npos=pos+1;
long long ans=pow(10,pos+1);
//cout<<ans<<' '<<leave<<' '<<npos<<endl;
//先把开头的0-9判掉
long long hhh=leave/pow(5,pos+1);
leave%=(long long)pow(5,pos+1);
ans=ans*(hhh+1);
//cout<<hhh<<' '<<leave<<' '<<ans<<' '<<npos<<endl;
while(npos){
long long fst=ans/(long long)pow(10,npos)%10;
//cout<<fst<<endl;
--npos;
hhh=leave/(long long)pow(5,npos);
leave%=(long long)pow(5,npos);
ans+=2*hhh*(long long)pow(10,npos);
if(fst%2==0){//偶数
ans+=(long long)pow(10,npos);
}
//cout<<hhh<<' '<<leave<<' '<<ans<<endl;
}
cout<<ans<<endl;
return 0;
}