zoukankan      html  css  js  c++  java
  • HDU 3183 RMQ(指定区间的最值)

    A Magic Lamp

    题意很简单,自己好好读一下。

    因为留下来的数要构成最小的数,所以我们可以先找字段里面最小的数字,
    比如样例 a=178534 4 ;也就是说我们需要按顺序找到3个最小数,比如找第一个小的数,只能在a[0]...a[3]中找,第二个小的数,只能在a[1]...a[4]中找,诸如这样的找法一直找到所有需要找的数。
    刚开始我是这样写的;

    #include<bits/stdc++.h>
    using namespace std;
    struct node
    {
        int x;
        int d;
    };
    node a[1010];
    int m;
    char ch[1010];
    int main()
    {
        while(scanf("%s ",ch)!=EOF)
        {
            scanf("%d",&m);
            int len=strlen(ch);
            for(int i=0; i<len; i++)
            {
                a[i].x=ch[i]-'0';
                a[i].d=0;
            }
            int dd=len-m;
            int b[1010];
            for(int i=0; i<dd; i++)
            {
                int mm=99999,flag;
                for(int j=i; j<i+m+1; j++)
                {
                    if(a[j].x<mm && !a[j].d)
                    {
                        mm=a[j].x;
                        flag=j;
                    }
                }
                a[flag].d=1;
                b[i]=mm;
            }
            int ans=0;
            for(int i=0; i<dd; i++)
            {
                ans=ans*10+b[i];
            }
            cout<<ans<<endl;
    
        }
        return 0;
    }
    

    但是这样的弊端就是,有可能找到的数字的顺序是不对的,刚开始没意识到,也是今天晚上打cf之前想到的;

    这是ST(就是个动态规划的思想)的解法,只有理解了RMQ的f[i][j]跳转的方式和意义,就能很好的应用了。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define inf 0x3f3f3f3f3f
    char a[1010],num[1010];
    int len,n;
    int f[1010][15];
    int Min(int i,int j)
    {
        return a[i]<=a[j]?i:j;
    }
    void RMQ(int n)
    {
        for(int i=0; i<n; i++)
            f[i][0]=i;
        for(int j=1; j<=(int)(log(1.0*n)/log(2.0)); j++)
        {
            for(int i=0; i+(1<<j)-1<n; i++)
            {
                f[i][j]=Min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int qq(int l,int r)
    {
        int x=(int)(log(1.0*(r-l+1))/log(2.0));
        return Min(f[l][x],f[r-(1<<x)+1][x]);
    }
    int main()
    {
        while(scanf("%s ",a)!=EOF)
        {
            scanf("%d",&n);
            len=strlen(a);
            RMQ(len);
            n=len-n;
            int i=0,j=0;
            while(n--)
            {
                i=qq(i,len-n-1);
                num[j++]=a[i++];
            }
            for(i=0; i<j; i++)
                if(num[i]!='0')
                break;
            if(i==j)
            {
                printf("0
    ");
                continue;
            }
            else
            {
                for( ;i<j; i++)
                    printf("%c",num[i]);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Electron+Vue开发跨平台桌面应用
    vue-cli3.0 脚手架搭建项目的过程详解
    dart-sass与node-sass介绍
    创建vue-cli4项目,报错 ERROR command failed: yarn
    CSS Grid 网格布局教程
    总结5种自适应方式
    前端实战:electron+vue3+ts开发桌面端便签应用
    SDK 和 API 的区别是什么?
    Pinia 快速入门
    返回数组中最大的三个数
  • 原文地址:https://www.cnblogs.com/zzulipomelo/p/4982864.html
Copyright © 2011-2022 走看看