Codeforces Round 861 (Div. 2) C. Unlucky Numbers

Problem - C - Codeforces

 

 题目大意:在两个数的闭区间中取 一个数字,让当前数字,各个位置上单独数字的最大值 最小值的差最小。

思路:数据范围过大,可以没办法暴力,因为各个位置上的数字,所以可以从这里入手,来进行枚举暴力。具体的看代码里面的注释,写的详细。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include <unordered_map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
inline char nc() {
    static char buf[1000000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
}
template <typename _Tp> inline void read(_Tp&sum) {
    char ch = nc(); sum = 0;
    while (!(ch >= '0'&&ch <= '9')) ch = nc();
    while (ch >= '0'&&ch <= '9') sum = (sum << 3) + (sum << 1) + (ch - 48), ch = nc();
}
inline __int128 read128(){
    __int128 x = 0, f = 1;
    char ch128 = getchar();
    while(ch128 < '0' || ch128 > '9'){
        if(ch128 == '-')
            f = -1;
        ch128 = getchar();
    }
    while(ch128 >= '0' && ch128 <= '9'){
        x = x * 10 + ch128 - '0';
        ch128 = getchar();
    }
    return x * f;
}
inline void print128(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print128(x / 10);
    putchar(x % 10 + '0');
}
//struct dian{
//    double x,y;
//}A,B,C,D,E,F;//点
//cin>>A.x>>A.y>>B.x>>B.y>>C.x>>C.y>>D.x>>D.y>>E.x>>E.y>>F.x>>F.y;
//double len(dian x,dian y){
//    return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));
//}//两点之间距离
//double xj(dian x,dian y,dian z){
//    x.x-=y.x;
//    x.y-=y.y;
//    z.x-=y.x;
//    z.y-=y.y;
//    return x.x*z.y-x.y*z.x;
//}//叉积
int n,t;
ll a,b;
string a1;
ll fx(ll x,int cmax){
    a1=to_string(x);
    ll na=0;
    for (int i =0; i<10; i++) {
        if (i+cmax>9) {
            break;
        }
        int dmax=i+cmax;
        ///i dma枚举最最小值 最大值的情况
        ll fir=0;
        for (int j=0; j<a1.size(); j++) {
            ///从第一位开始向后枚举
            for (int k=dmax; k>=i; k--) {
                ll sec=fir*10+k;
                ///sec为当前位取k的情况
                for (int l=j+1; l<a1.size(); l++) {
                    sec=sec*10+i;
                    ///如果当前枚举符合 那么之后的数字必定大于等于最小位
                }
                if (sec<=b) {
                    fir=fir*10+k;
                    break;
                    ///枚举当前位小于r才可以进位,如果大于 r  则不符合,不需要进位break 来保存
                }
            }
            na=max(na, fir);
            ///答案尽量大,因为是大于a可以输出    因为前边小于b  fir的值才会改变,所以答案一定是小于b的
        }
    }
    return na;
}
void wanyurukong(){
    cin>>a>>b;
    for (int i =0; i<10; i++) {
        if (fx(b, i)>=a) {
            ///i是枚举最大和最小相差的值,从小到大枚举,所以只要符合,直接输出
            printf("%lld\n",fx(b, i));return;
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        wanyurukong();
    }
    //wanyurukong
    return 0;
}
 

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值