zoukankan      html  css  js  c++  java
  • UVa 11491 Erasing and Winning (贪心,单调队列或暴力)

    题意:给一个数字(开头非0),拿掉其中的d个数字,使剩下的数字最大(前后顺序不能变)。

    析:拿掉d个数字,还剩下n-d个数字。相当于从n个数字中按先后顺序选出n-d个数字使组成的数字最大,当然采用窗口滑动优先选取大的。

    也就是说,当然第一位最大,这个数就最大了,所以这是一个贪心算法。我开始并不知道有这个算法,

    所以开始我是暴力的,700ms,要是数据量再大一点,就TLE了。所以我想肯定有高效率的算法,查了查,原来还有这个。

    先说我想法,首先在前d个数字中选最大的,然后在从这个数字到d+1个中选最大的,依次往后,贪心。

    想法很简单,就是太慢了。然后我再说单调队列,就是用一个队列,里面是从大到小排的,必须是这样的,先对前d-1个进行预处理,

    把太小的都删了,然后一个一个的放,放的时候把小于该值的都删了,保证是从大到小的,每次从队首取元素,保证是最大的。

    如果还觉得太慢了,可以在删除元素时用二分查找,更快的确定位置。

    代码如下:

    暴力代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    const int maxn = 100000 + 10;
    int a[maxn];
    char s[maxn];
    
    int main(){
    //    freopen("in.txt", "r", stdin);
        int n, d;
        while(scanf("%d %d", &n, &d) == 2 && n){
            scanf("%s", s);
            for(int i = 0; i < n; ++i)  a[i] = s[i] - '0';
    
            int indx = 0;
            int st = 0, ed = d+1;
            while(true){
                int m = -1;
                for(int i = st; i < ed; ++i){
                    if(a[i] > m){ m = a[i];  st = i + 1; }
                    if(9 == m)  break;
                }
                printf("%d", m);
                if(ed == n)  break;
                ++ed;
            }
    
            printf("
    ");
        }
        return 0;
    }
    

    单调队列代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    const int maxn = 100000 + 10;
    struct node{
        int id, val;
    };
    char s[maxn];
    node a[maxn], q[maxn];
    
    void solve(int k, int n){
        int front = 0, rear = -1;
        for(int i = 0; i < k; ++i){
            while(front <= rear && q[rear].val < a[i].val)  --rear;//预处理前d个,要保证是单调的,小于的都删掉
            q[++rear] = a[i];
        }
    
        int id = -1;
        for(int i = k; i < n; ++i){
            while(front <= rear && q[rear].val < a[i].val)  --rear;//同上
            q[++rear] = a[i];
    
            while(q[front].id <= id)  ++front;//因为是有顺序的,要往后放
            printf("%d", q[front].val);
            id = q[front].id;
        }
        printf("
    ");
    }
    
    int main(){
    //    freopen("in.txt", "r", stdin);
        int n, d;
        while(scanf("%d %d", &n, &d) == 2 && n){
            scanf("%s", s);
            for(int i = 0; i < n; ++i){
                a[i].id = i;
                a[i].val = s[i] - '0';
            }
    
            solve(d, n);
        }
        return 0;
    }
    
  • 相关阅读:
    Go--指针
    Go--struct
    Go--函数
    Go基础
    流程控制
    Go前言
    变量与常量
    Django(三):HttpRequest和HttpResponse
    Django(二):url和views
    tensorflow(一):图片处理
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5563615.html
Copyright © 2011-2022 走看看