zoukankan      html  css  js  c++  java
  • ST表——HDU-3183

    题目链接

    题目含义

    给出一串数以及m

    要求删除m个数后,让剩下的一串数组成的整数最小

    题目分析

    首先,通过案例可以发现一个规律

    在满足留下足够的数字的条件下, 剩下的第一个数一定是能取得的最小的数

    (也可能是0)

    所以我们先通过ST表找出每个区间的最小数字

    然后在满足至少留有len-1个数字的情况下,在前面找出最小的数作为留下的第一个数

    然后剩下的数必须在前一个数之后选,同样选能选的最小的数,最后就能得到答案了

    但是如果首数字是0的话,就要限制一下输出,让首数字非0或者整数为0

    题目代码

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<math.h>
    using namespace std;
    typedef long long LL;
    const int maxn=1007;
    int st[maxn][10],a[maxn];
    char str[maxn];
    int m,n;
    void ST(){
        for(int i=0;i<n;i++)
            st[i][0]=i;
        int t=log2(n);
        for(int j=1;j<=t;j++)
        for(int i=0;i+(1<<j)-1<n;i++){
            if(a[st[i][j-1]]<=a[st[i+(1<<(j-1))][j-1]])
                st[i][j]=st[i][j-1];
            else st[i][j]=st[i+(1<<(j-1))][j-1];
        }
    }
    int query(int l,int r){
        int len=r+1-l;
        int t=log2(len);
        if(a[st[l][t]]<=a[st[r+1-(1<<t)][t]])
            return st[l][t];
        else return st[r+1-(1<<t)][t];
    }
    int main(){
        while(~scanf("%s%d",&str,&m)){
            n=strlen(str);
            for(int i=0;i<n;i++)
                a[i]=str[i]-'0';
            ST();
            int len=n-m,cnt=0,l=0;
            int ans[maxn];
            for(int i=0;i<len;i++){
                ans[cnt]=query(l,n-len+i);
                l=ans[cnt++]+1;
            }
            int nn=0;
            while(a[ans[nn]]==0)nn++;
            if(nn>=cnt)printf("0
    ");
            else {
                for(int i=nn;i<cnt;i++)
                    printf("%d",a[ans[i]]);
                printf("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    C#里边的控件缩写大全(比较规范)
    jQuery的一些备忘
    有趣的史实~
    值类型 VS 引用类型~
    一道笔试题和UML思想 ~
    数据绑定以及Container.DataItem几种方式与用法分析
    用户控件与自定义控件的异同
    .NET资源站点汇总~
    C#中抽象类和接口的区别
    弹出窗口的一些东西(一),备忘~
  • 原文地址:https://www.cnblogs.com/helman/p/11348418.html
Copyright © 2011-2022 走看看