• A Magic Lamp HDU


    题意就是数字串删m个字符让剩下的最小,剩下可含前导0

    贪心是删掉第一个s[i]满足s[i]>s[i+1]

    用rmq的话可以这样想,剩下数字串的最高位一定是s[1]~s[m+1]中的最小,设为s[x]

    次高位就是s[x+1]~s[m+2]中的最小……递推一下就好

    //#include<bits/stdc++.h>
    #include<stdio.h>
    #include<algorithm>
    #include<queue>
    #include<string.h>
    #include<iostream>
    #include<math.h>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    using namespace std;
    #define ll long long
    #define ld long double
    #define pb push_back
    #define FOR(a) for(int i=1;i<=a;i++)
    //const int inf=0x3f3f3f3f;
    #define inf 0x3f3f3f3f
    const long long Linf=9e18;
    const int maxn=1e5+90; 
    
    char s[maxn];
    
    int n,m;
    char num[maxn];
    
    int _min(int i,int j){
    	return s[i]<=s[j]?i:j;
    }
    
    int MIN[maxn][20];
    void ST(){
    	for(int i=1;i<=n;i++)MIN[i][0]=i;
    	int k=log( (double)(n+1) )/log(2.0);
    	for(int j=1;j<=k;j++)
    		for(int i=1;i+(1<<j)-1<=n;i++)
    			MIN[i][j]=_min(MIN[i][j-1],MIN[i+(1<<(j-1))][j-1]);
    }
    int rmq_min(int l,int r){
    	int k=log((double)(r-l+1))/log(2.0);
    	return _min(MIN[l][k],MIN[r-(1<<k)+1][k]);
    }
    
    int main(){
    	while(~scanf("%s%d",s+1,&m)){
    		int len=strlen(s+1);
    		n=len;m=len-m;	//选m个数
    		ST();
    		int i=1,j=1;
    		while(m--){
    			i=rmq_min(i,len-m);
    			num[j++]=s[i++];
    		}
    		for(i=1;i<j;i++){			//忽略前导0
    			if(num[i]!='0')break;
    		}
    		if(i==j){
    			puts("0");continue;		//全0串
    		}
    		while(i<j){
    			printf("%c",num[i]);
    			i++;
    		}
    		puts("");
    	}
    }


  • 相关阅读:
    字符串方法
    文件上传路径转虚拟路径
    表结构转excel
    @ModelAttribute
    select
    查询详情在模态框展示
    时间
    mybatis一对多
    bootstrap tab页
    为什么不建议使用WordPress呢?
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611248.html
Copyright © 2020-2023  润新知