http://acm.hdu.edu.cn/showproblem.php?pid=3183

A Magic Lamp

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8310    Accepted Submission(s): 3296

Problem Description
Kiki
likes traveling. One day she finds a magic lamp, unfortunately the
genie in the lamp is not so kind. Kiki must answer a question, and then
the genie will realize one of her dreams.
The question is: give you
an integer, you are allowed to delete exactly m digits. The left digits
will form a new integer. You should make it minimum.
You are not allowed to change the order of the digits. Now can you help Kiki to realize her dream?
 
Input
There are several test cases.
Each
test case will contain an integer you are given (which may at most
contains 1000 digits.) and the integer m (if the integer contains n
digits, m will not bigger then n). The given integer will not contain
leading zero.
 
Output
For each case, output the minimum result you can get in one line.
If the result contains leading zero, ignore it.
 
Sample Input
178543 4
1000001 1
100001 2
12345 2
54321 2
 
Sample Output
13
1
0
123
321
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  3188 3189 3184 3185 3186 
 
   思路主要是这样的: 因为需要你删除m个数使得结果最小,所以每次对字符串进行一次遍历,从前往后,只要a[i]>a[j] (j的位置为i后面未标记的第一个)  则对a[i]进行一次标记(赋赋值)将其除外,进行n次遍历,这样就删除了n个数字。因为删除的都是和后面比较相比下大的,所得结果当然就最小了。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include <stdio.h>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
using namespace std;
] ;
];
];
int main()
{
    int n , m ;
    while(~scanf("%s%d" , s , &m))
    {
        n = strlen(s);
        memset(a ,  , sizeof(a));
         ; i < n ; i++)
            a[i] = s[i] - ';
         ; i < m ; i++)//找到m个要删除的数
        {
             ; j < n ; j++)
            {
              //  if(a[j] > 0)//排除标记的
              //  {
                    int k ;
                     ; k < n ; k++)
                    {
                        )//排除标记的
                        break ;
                    }
                    if(a[j] > a[k])//找第一个开始递减的数
                    {
                        a[j] = - ;
                        break ;
                    }
              //  }
            }
        }
         , len =  ;
         ; i < n ; i++)
        {
            )//去前置零
                continue ;
            )
                continue ;
            b[len++] = a[i];
            )
                flag =  ;
        }
         ; i < len ; i++)
            printf("%d" , b[i]);
        )
            printf(");
        printf("\n");
    }
     ;
}

RMQ:

因为要找n-m个数,删除m个数。所以原数的第1位到m+1位的数字中最小的那位(假设是第i位)肯定是n-m位数的第一位。(想想为什么)

这样我们就找到了第一位a[i],接下来我们在从第i+1位数到m+2位数中找最小的那位,这个肯定是n-m位数的第二位。

以此类推,找够n-m位即可。

RMQ函数要做点修改。dmin[i][j]=k表示的是区间[i,i+(1<<j)-1]内最小值的下标而不是值了。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include <stdio.h>
#include <string.h>
#include <vector>
#define ME(x , y) memset(x , y , sizeof(x))
#define SF(n) scanf("%d" , &n)
#define rep(i , n) for(int i = 0 ; i < n ; i ++)
#define INF  0x3f3f3f3f
using namespace std;
] ;
];
] , dp[][];
int m , n ;

int Min(int x , int y)
{
    return s[x] <= s[y] ? x : y ;
}

void RMQ()
{
    memset(dp ,  , sizeof(dp));
      ; i < n ; i++)
        dp[i][] = i ;
     ; j <  ; j++)
    {
         ; i < n ; i++)
        {
             << j) -  < n)
            {
                dp[i][j] = Min(dp[i][j-] , dp[i+(<<j-)][j-]);
            }
        }
    }

}

int query(int l , int r)
{
    );
    <<k)+][k]);
}

vector<int>v;
int main()
{
    while(~scanf("%s%d" , s , &m))
    {
        v.clear();
        n = strlen(s);
        RMQ();
        m = n - m ;
         ;
        while(m--)
        {
            // 在 n - m 区间至少留一个数
            pos = query(pos , n - m - );//求的是最小值的下标
            v.push_back(pos);
            pos +=  ;
        }
         ;
         ; i < v.size() ; i++)
        {
            if(flag)
            {
                flag =  ;
                cout << s[v[i]];
            }
            ')
            {
                flag =  ;
                cout << s[v[i]] ;
            }
        }
        if(!flag)
            cout <<  ;
        cout <<endl ;
    }

     ;
}

RMQ(鸽巢原理或字符串操作)的更多相关文章

  1. hdu 3183 rmq+鸽巢原理

    题目大意: 给你一个数字字符串序列,给你要求删掉的数字个数m,删掉m个数使的剩下的数字字符串的之最小.并输出这个数字: 基本思路; 这题解法有很多,贪心,rmq都可以,这里选择rmq,因为很久没有写r ...

  2. [BZOJ4722]由乃[鸽巢原理+bitset+倍增]

    题意 给定长为 \(n\) 序列 \(a\) ,要求支持两种操作: \(1.\) 询问在一个区间 \([l,r]\) 中,是否能够选出两个交集为空的集合 $ \rm X ,Y$, 使得 \(\sum_ ...

  3. POJ2356 Find a multiple 抽屉原理(鸽巢原理)

    题意:给你N个数,从中取出任意个数的数 使得他们的和 是 N的倍数: 在鸽巢原理的介绍里面,有例题介绍:设a1,a2,a3,……am是正整数的序列,试证明至少存在正数k和l,1<=k<=l ...

  4. 51nod 1574 排列转换(贪心+鸽巢原理)

    题意:有两个长度为n的排列p和s.要求通过交换使得p变成s.交换 pi 和 pj 的代价是|i-j|.要求使用最少的代价让p变成s. 考虑两个数字pi和pj,假如交换他们能使得pi到目标的距离减少,p ...

  5. Two progressions(CodeForces-125D)【鸽巢原理】

    题意:将一列数划分为两个等差数列. 思路:首先,我要吹爆鸽巢原理!!!真的很强大的东西!!! 加入能完成题设操作,则前三个数中,必有至少两个数在同一序列,枚举三种情况(a1 a2,a2 a3,a1 a ...

  6. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  7. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理

    Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   ...

  8. cf319.B. Modulo Sum(dp && 鸽巢原理 && 同余模)

    B. Modulo Sum time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  9. poj 2356 Find a multiple(鸽巢原理)

    Description The input contains N natural (i.e. positive integer) numbers ( N <= ). Each of that n ...

随机推荐

  1. 前端开发HTML&css入门——常用的标签以及一个小练习

    meta标签 <!doctype html> <html> <head> <meta charset="utf-8" /> < ...

  2. openstack stein部署手册 4. glance

    # 建立数据库用户及权限 create database glance; grant all privileges on glance.* to glance@'localhost' identifi ...

  3. 团队中的 Git 实践

    转载自:https://segmentfault.com/a/1190000004963641 本文首发于欧雷流.由于我会时不时对文章进行补充.修正和润色,为了保证所看到的是最新版本,请阅读原文. 在 ...

  4. 记一次 gunicorn 启动 flask 出问题的经历

    出错现象: gunicorn+nginx+flask 部署项目, 部署过程没问题,项目也正常启动了,但是一旦访问接口,就会报错: Traceback (most recent call last): ...

  5. CSS3 Animations

    CSS Animations 是CSS的一个模块,它定义了如何用关键帧来随时间推移对CSS属性的值进行动画处理.关键帧动画的行为可以通过指定它们的持续时间,它们的重复次数以及它们如何重复来控制. an ...

  6. 前端每日实战:98# 视频演示如何用纯 CSS 创作一只愤怒小鸟中的绿猪

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/VBGWqX 可交互视频 此视频是可 ...

  7. Flask路由之重定向

    Flask框架提供了请求重定向功能,只需要使用 redirect_to即可, 示例代码如下: from flask import Flask, render_template, request, re ...

  8. [JSOI2004]平衡点 / 吊打XXX 题解

    预备概念: 金属退火:将金属缓慢加热到一定温度,保持足够时间,然后以适宜速度冷却 温度:一个逐渐减小的参数,表示接受次优解的概率 模拟退火是一种解决复杂问题的算法,相当于贪心,但以一个逐渐减小的该率接 ...

  9. web css

    CSS圆角——透明圆角化背景图片 序言:第一章中我介绍了最基本的纯CSS圆角框的实现原理,并给出Demo,在本章中会对上一个模型作一些新的创新,实现将背景图片透明圆角化.并给出一些漂亮的通用演示效果. ...

  10. IDEA搭建spingboot项目

    1.Springboot2.x是依赖于JDK1.8及以上版本的.因此先在电脑上安装JDK1.8,由于公司的项目用的是JDK1.7,所以要在JDK1.7的基础上在安装JDK1.8,让两者同时存在于电脑上 ...