UVa #11491 Erasing and Winning (习题8-4)

86 篇文章 0 订阅

这道题吭哧了挺久的,主要是贪心算法设计的有问题。。


最开始的想法是:从第一个数开始在最大的范围内搜索最大值,作为第一位数字,之后从这个最大值的下一位开始,重复这个搜索,直到删除的数字达到上限。这样做重复了很多无用功,会TLE


最后改为:从前往后扫描,每次遇到 ai > aj (i<j) 的情况,则从i开始往前扫,删掉所有小于ai的。


另外还有一些细节需要小心,比如连续很多位相同的数字。



Run Time:0.033s

#define UVa  "8-4.11491.cpp"
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<ctype.h>
#include<vector>

using namespace std;

//Global Variables. Reset upon Each Case!
const int maxn = 100000 + 10;
int del[maxn];
/

int main() {
    int N, D;
    while(scanf("%d%d", &N, &D) && (N || D) ) {
        memset(del, 0, sizeof(del));
        char a[maxn];
        scanf("%s", a);

        int cnt = 0;
        int prev = -1;
        while(cnt < D && cnt != prev) {
            prev = cnt;
            int last = a[0], lastpos = 0;
            for(int i = 1; i < N; i ++) {
                if(!del[i]) {
                    if(!del[lastpos] && a[i] > last && cnt < D) {
                        del[lastpos] = 1;
                        cnt ++;
                        for(int j = i - 1; j >= 0; j --) {              //scan backward. delete all that smaller than a[i], until meet a[j] >= a[i].
                            if(!del[j] && a[j] < a[i] && cnt < D) {
                                del[j] = 1;
                                cnt ++;
                            }
                            if(!del[j] && a[j] >= a[i]) break;
                        }
                    }
                    last = a[i];
                    lastpos = i;
                }
            }
        }
        if(cnt == prev) {       //can't delete anymore: the sequence is decreasing, select first N-D items only.
            int p = N-1;
            while(cnt < D) {
                if(!del[p] && cnt < D) {
                    del[p] = 1;
                    cnt ++;
                }
                p--;
            }
        }
        for(int i = 0; i < N; i ++) {
            if(!del[i]) printf("%c", a[i]);
        }
        printf("\n");
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值