• 2020牛客多校第四场D-Dividing Strings


    https://ac.nowcoder.com/acm/contest/5669/D

    题意

    给出一个由数字构成的字符串,把字符串分成若干不含前导零的子串,求子串间最大差值的最小值

    题解

    首先可以分成全部长度为1,所以答案一定小于等于9

    所以划分只有两种情况,要么全部长度相等,要么最长的和最短的相差1

    对于第一种情况,直接枚举约数扫一遍

    对于第二种情况,合法的一定是10000...y和9999...x这样类似的,先找到构成10000...y的长度是多少(len),然后分别判断len是否可行和len-1是否可行

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    struct READ {
        inline char read() {
        #ifdef _WIN32
            return getchar();
        #endif
            static const int IN_LEN = 1 << 18 | 1;
            static char buf[IN_LEN], *s, *t;
            return (s == t) && (t = (s = buf) + fread(buf, 1, IN_LEN, stdin)), s == t ? -1 : *s++;
        }
        template <typename _Tp> inline READ & operator >> (_Tp&x) {
            static char c11, boo;
            for(c11 = read(),boo = 0; !isdigit(c11); c11 = read()) {
                if(c11 == -1) return *this;
                boo |= c11 == '-';
            }
            for(x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0');
            boo && (x = -x);
            return *this;
        }
    } in;
    
    const int N = 2e5 + 50;
    char s[N];
    int n;
    int ans;
    int cmx[N], cmn[N], cnow[N];
    bool cmp(int a[], int b[], int len) {
        for (int i = 1; i <= len; i++) if (a[i] != b[i]) return a[i] > b[i];
        return 0;
    }
    void copy(int a[], int b[], int len) {
        for (int i = 1; i <= len; i++) a[i] = b[i];
    }
    void check(int len) {
        for (int j = 1; j <= len; j++) cmn[j] = 9, cmx[j] = 0;
        for (int j = 1; j <= n; j++) {
            if (j % len == 1 && s[j] == '0') return;
            cnow[(j-1)%len+1] = s[j] - '0';
            if (j % len == 0) {
                if (cmp(cnow, cmx, len)) copy(cmx, cnow, len);
                if (cmp(cmn, cnow, len)) copy(cmn, cnow, len); 
            }
        }
        int mni = 9;
        for (int j = len; j >= 1; j--) {
            int t = cmx[j] - cmn[j];
            if (t < 0) cmx[j - 1]--, t += 10;
            if (j == len) mni = t;
            else if (t > 0) return;
        }
        ans = min(ans, mni);
    }
    int find() {
        for (int now = 1; now <= n; now++) {
            if (s[now] == '1') {
                int l = now;
                while (now < n && s[now + 1] == '0') now++;
                if (now < n && s[now + 1] != '9') now++;
                return now - l + 1;
            }
        }
        return -1;
    }
    int calc(int len) {
        int n1 = -1, n9 = 10;
        for (int now = 1; now <= n; now++) {
            int l = now;
            if (s[now] == '1') {
                while (now < n && s[now + 1] == '0') now++;
                if (now < n && now - l + 1 < len && s[now + 1] != '9') now++;
                if (now - l + 1 != len) return 9;
                n1 = max(n1, s[now] - '0');
            }
            else {
                now--;
                while (now < n && s[now + 1] == '9' && now - l + 1 < len - 1) now++;
                if (now < n && now - l + 1 < len - 1) now++;
                if (now - l + 1 != len - 1) return 9;
                n9 = min(n9, s[now] - '0');
            }
        }
        if (n9 == 10 || n1 == -1) return 9;
        return n1 + 10 - n9;
    }
    int main() {
        int t; scanf("%d", &t);
        while (t--) {
            scanf("%d", &n);
            scanf("%s", s + 1);
            int mxi = 0, mni = 1e9;
            for (int i = 1; i <= n; i++) {
                mxi = max(mxi, s[i] - '0');
                mni = min(mni, s[i] - '0');
            }
            ans = mxi - mni;
            for (int i = 2; i < n; i++) {
                if (n % i == 0) check(i);
            }
            int len = find();
            if (len > 1) ans = min(ans, calc(len));
            if (len > 2) ans = min(ans, calc(len - 1));
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    .net jquery ajax应用(后台)
    .net jquery ajax应用(前端)
    echarts 添加Loading 等待。
    js将数字转换为带有单位的中文表示
    关于Pre-bound JDBC Connection found! HibernateTransactionManager does not 异常小结
    java 并发容器一之ConcurrentHashMap(基于JDK1.8)
    java 并发容器一之BoundedConcurrentHashMap(基于JDK1.8)
    23中java设计模式(1)-- 策略模式
    解决Eclipse自动补全变量名的问题
    Tomcat+Jenkins+SonarQube+SVN+Maven 集成自动化环境搭建(Windows10环境下)
  • 原文地址:https://www.cnblogs.com/artoriax/p/13590063.html
Copyright © 2020-2023  润新知