2020牛客暑期多校训练营(第四场)D-Dividing Strings 贪心乱搞

题意

给一个长度为\(n\)的数字串\(s\),现在让你将这个数字串分成若干个小段,每段的值即为它代表的数字,使最大值和最小值的差值最小。

分析

Code

#include<bits/stdc++.h>
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define per(i,n,x) for(int i=n;i>=x;i--)
#define sz(a) int(a.size())
#define rson mid+1,r,p<<1|1
#define pii pair<int,int>
#define lson l,mid,p<<1
#define ll long long
#define pb push_back
#define mp make_pair
#define se second
#define fi first
using namespace std;
const double eps=1e-8;
const int mod=1e9+7;
const int N=1e5+10;
const int inf=1e9;
int T,n;
char s[N];
int sum[N];
int cal(string a,string b){
    int l=b.size();
    reverse(a.begin(), a.end());
    reverse(b.begin(), b.end());
    int cnt=0;
    for(int i=0;i<l;i++){
        if(a[i]<b[i]){
            a[i]+=10;
            a[i+1]--;
        }
        a[i]-=b[i]-'0';
    }
    reverse(a.begin(),a.end());
    for(char x:a){
        x-='0';
        cnt=cnt*10+x;
        if(cnt>9) return inf;
    }
    return cnt;
}
int gao(int x){
    for(int i=1;i<=n;i++){
        if(i%x==1&&s[i]=='0') return inf;
    }
    string a,b,t;
    rep(i,1,n){
        t.pb(s[i]);
        if(i%x==0){
            if(a.empty()||a<t) a=t;
            if(b.empty()||b>t) b=t;
            t="";
        }
    }
    return cal(a,b);
}
int sol(int x){
    int c1=-1,c2=10;
    for(int i=1;i<=n;){
        if(s[i]=='1'){
            if(i+x<=n&&sum[i+x-1]-sum[i-1]==1){
                c1=max(c1,s[i+x]-'0');
                i+=x+1;
            }else return 9;
        }else{
            if(i+x-1<=n&&sum[i+x-2]-sum[i-1]==(i+x-2-i+1)*9){
                c2=min(c2,s[i+x-1]-'0');
                i+=x;
            }else return 9;
        }
    }
    if(c1==-1||c2==10) return 9;
    return c1+10-c2;
}
int main(){
    //ios::sync_with_stdio(false);
   // freopen("data.in","r",stdin);
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        scanf("%s",s+1);
        int mn=1,mx=1;
        rep(i,1,n){
            if(s[i]>s[mx]) mx=i;
            if(s[i]<s[mn]) mn=i;
            sum[i]=sum[i-1]+s[i]-'0';
        }
        int ans=s[mx]-s[mn];
        for(int i=1;i<=n;i++) if(n%i==0&&n/i>=2){
            ans=min(ans,gao(i));
        }
        for(int i=1;i<=n-1;i++){
            ans=min(ans,sol(i));
        }
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2020-07-24 18:39  xyq0220  阅读(250)  评论(0编辑  收藏  举报