uva 11491:Erasing and Winning(贪心)

题意:给一个长n(n<10^5)位的数,删除d位,求删除后最大的数。(原数无前导0)

思路:从前往后扫,如果a[i] > a[i-1],则删除a[i-1]。我暴力的用链表实现了……

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <list>
using namespace std;

#define N 100020
char str[N];
int main() {
    int n, d;
    while (scanf("%d%d",&n, &d) != EOF) {
        if (n == 0 && d == 0) break;
        scanf("%s", str);
        list<int> num;
        num.push_back(10);
        for (int i = 0; str[i]; i++) {
            num.push_back(str[i]-‘0‘);
        }
        num.push_back(10);

        list<int>::iterator hd, ed, tmp;
        hd = num.begin();
        ed = num.begin();
        hd++;
        while (d) {
            if (*hd > *ed) {
                num.erase(ed);
                hd--;
                ed = hd;
                hd++;

                d--;
            } else {
                hd++;
                ed++;
            }
        }
        num.pop_front();
        num.pop_back();
        for (hd = num.begin(); hd != num.end(); hd++) {
            printf("%d", *hd);
        }
        puts("");
    }
    return 0;
}

然而实际上,可以一边输入一边处理(笨笨的)

别人的代码:

#include <cstdio>

int n,m,a;
int t,s[100009];

int main()
{
    LOOP:
    {
        scanf("%d%d%*c",&n,&m);
        if (n==0 && m==0) return 0;
        m=n-m;
        t=0;
        for (int i=0;i<n;++i)
        {
            a=getchar()-‘0‘;
            while (t && t+n-i>m && a>s[t-1]) --t;
            if (t<m) s[t++]=a;
        }
        for (int i=0;i<t;++i) printf("%d",s[i]);
        putchar(‘\n‘);
    }
    goto LOOP;
}
时间: 2024-08-07 08:40:05

uva 11491:Erasing and Winning(贪心)的相关文章

【思路、优化】UVa 11491 - Erasing and Winning

Juliano is a fan of the TV show Erasing and Winning, where participants are selected in a draw and receive money for taking part in the show. In the show, the presenter writes a number of N digits in a board. The participant must then erase exactly D

UVA 11491 Erasing and Winning 奖品的价值 (贪心)

题意:给你一个n位整数,让你删掉d个数字,剩下的数字要尽量大. 题解:因为最后数字位数是确定的,而且低位数字对答案的贡献是一定不及高位数字的,所以优先选择选最大且最靠左边的数字,但是有一个限制,选完这个数字以后右边剩下的数字要保证足够接下来的选择,所以我想到了优先队列,记录一个信息,选的数字所在的位置,以及上一个数字所在的位置,如果当前出队的数字在上一个选的位置前面就直接丢掉,每次选完一个以后剩下要选的数字就减少了,满足限制的条件的数字会增加,再把新的待选数字加入队列. #include<bit

UVa 11491 Erasing and Winning 题解

难度:α 用时:30 min 题目:?? 这是个裸贪心题. 题目要求在某数字字符串中删去给定个数的字符,使剩下来的数字最大. 那么不难想到用队列.线性复杂度.0 ms. 每读入一个数,就把之前比较小的拿掉. 注意不能拿太多,否则长度不够. 队满了也不能继续放.(除非有更大的元素可以把队尾的怼下去) 1 for (int i = 0; i < d; i++) { 2 char c = getchar(); 3 while (it > 0 && ans[it] < c &am

UVA 11491 Erasing and Winning

#include<bits/stdc++.h> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int maxn=1000100; const int INF=1

11491 - Erasing and Winning(贪心)

一开始真的没想到这竟然是一道贪心题目.  不过后来仔细想想也就明白了. 我采取的做法是自前向后扫一遍,用一个指针rear动态维护答案数组中的最后一个元素,如果遇到一个比它大的数s[i],那么从它开始将它及其它之前的比s[i]小的数全部删除,并且用变量cnt记录删除的个数, 防止删除多了. 对于贪心算法的正确性我们不难用反证法来证明: 假设这样做不是最优的,那么如果不这样做,对于一个长度一定的答案,得到的结果一定小于这样做的结果. 但是还有可能少删了,也就是第三组样例那种情况,所以我们贪心结束后要

UVA11491-Erasing ans Winning(贪心)

Problem UVA11491-Erasing ans Winning Accept: 799  Submit: 5753Time Limit: 3000 mSec Problem Description Juliano is a fan of the TV show Erasing and Winning, where participants are selected in a draw and receive money for taking part in the show. In t

uva 1521 - GCD Guessing Game(贪心)

题目链接:uva 1521 - GCD Guessing Game 题目大意:给定一个数N,现在又一个数x,在1~N之间,现在每次可以猜一个数a,返回gcd(x,a),问说最少猜几次可以确定x. 解题思路:其实就将1~N里面的素数都要考虑一遍,因为有一个N的限制,所以每次选出来的素数的积不大于N即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const

uva 10026 Shoemaker&#39;s Problem(贪心+排序)

虽然是个水题,但是在一些细节上wa了几次,好像不支持'\b'退格符号,我用在了输出空格那,结果wa了...白白 wa了几次...题意是看的题解..今天只写了两道题,速度有点慢,得加快了,以后得先认真读懂题目,题目读懂了 就相当于做出来一半然后仔细动脑想想,有想法了再敲,不能盲目的做题.另外,热烈祝贺今天c++ primer看到 了100页 思路: 这道题是让给的数据是每件工作需要做的天数和每耽误一天所需要的费用,让求一个序列使得付费最小,如果有相同答 案把字典树最小的输出...输出的是序号,该件

uva 1016 - Silly Sort(置换+贪心)

题目链接:uva 1016 - Silly Sort 题目大意:给定一个长度为n的序列,每次操作可以交换任意两个数的位置,代价为两个数的和,求最小代价,将序列排成有序的. 解题思路:给定序列根据数的大小映射成一个置换,分解置换的循环,对于每个循环中,肯定是用值最小的逐个去交换的代价最小,但是要考虑,可以将最小的值与序列中最小值交换,用它代替去交换,最后再换回来.取两种情况中最优的. #include <cstdio> #include <cstring> #include <