*题意:

在给定区间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;
            }
        }
    }
}