*题意:
在给定区间l,r内,求出区间内翻转十进制后并去除前导0的最大值。
关键词
分类讨论,贪心
题解:
首先10的15次方要用long long ,但是用string就不怕超范围,还方便翻转。 先看x如果属于(1142005,1143255),那他开头一定含有公共部分“114",其次我们想让翻转后数更大,我们需要保证位数大的前提,在后面有更多的9,所以在第一个不同的位下,高位-1,后续位为9,让其更大,但这里就会有第一个特判。
如果r=1143999的话,第一个不同位3,不需要-1,故只需与r的翻转数取最大即可。
其次第二个特判就是r=1000...0000的话,区间内最大的翻转数就是r-1(l!=r)。
第三个特判就是l==r,那就只有一种答案直接翻转取值即可。
但是先取公共部分得先保证l与r位数相同,如果不同,比如(100,2510),那其翻转值最大应为四位,所以可以缩范围至(1000,2510),然后就可以重复刚开始的方法了。 最后用stoll()时可以帮助去除前导0,reverse(),可以快速翻转。
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
for(int i=1;i<=t;i++){
string l,r;
cin>>l>>r;
if(l.size()!=r.size()){
string s;
s=r;
reverse(s.begin(),s.end());
long long sum1=stoll(s);
if(sum1==1){
long long sum=stoll(r);
cout<<sum-1<<endl;
}
else{
l.clear();
l="1";
for(int j=1;j<r.size();j++){
l+='0';
}
}
}
if(l.size()==r.size()){
int num=-1;
string s;
for(int j=0;j<l.size();j++){
if(l[j]!=r[j]){
num=j;
break;
}
s+=l[j];
}
if(num==-1){
reverse(s.begin(),s.end());
long long sum=stoll(s);
cout<<sum<<endl;
}
else{
s+=(r[num]-1);
for(int j=1;j<r.size()-num;j++){
s+='9';
}
reverse(s.begin(),s.end());
reverse(r.begin(),r.end());
long long sum1=stoll(r);
long long sum=stoll(s);
sum=max(sum,sum1);
cout<<sum<<endl;
}
}
}
}

京公网安备 11010502036488号