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<<29;

int n,d;
int a[maxn];
int ans[maxn],cnt;
deque<int> q;

int main()
{
    freopen("in.txt","r",stdin);
    while(cin>>n>>d,n||d){
        REP(i,1,n) scanf("%1d",&a[i]);
        while(!q.empty()) q.pop_back();
        REP(i,1,d){
            while(!q.empty()&&q.back()<a[i]) q.pop_back();
            q.push_back(a[i]);
        }
        cnt=0;
        REP(i,d+1,n){
            while(!q.empty()&&q.back()<a[i]) q.pop_back();
            q.push_back(a[i]);
            ans[++cnt]=q.front();q.pop_front();
        }
        REP(i,1,cnt) printf("%d",ans[i]);
        puts("");
    }
    return 0;
}

单调队列维护划窗最值的题,一开始愣是写完了线段树才发现是划窗最值。。

时间: 2025-01-22 19:20:48

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(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()

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

11491 - Erasing and Winning(贪心)

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

UVa 11491 奖品的价值

https://vjudge.net/problem/UVA-11491 题意:一个n位整数,删除其中的d个数字,输出最大值. 思路:肯定从高位开始分析,代码如下. 1 #include<string> 2 #include<iostream> 3 using namespace std; 4 5 const int maxn = 100000 + 5; 6 7 int n, d; 8 char a[maxn]; 9 10 int main() 11 { 12 //freopen(

UVA-11491 Erasing and Winning (单调队列)

题目大意:给一个数字(开头非0),拿掉其中的d个数字,使剩下的数字最大(前后顺序不能变). 题目分析:拿掉d个数字,还剩下n-d个数字.相当于从n个数字中按先后顺序选出n-d个数字使组成的数字最大,当然采用窗口滑动优先选取大的. 代码如下: # include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; struct Num

uva11491 Erasing and Winning

边读入边处理 优化了速度一开始有想错了的地方.处理输入有点想用stringstream, 的问题在于他把字符串连续的数字作为一个整体,遇到空格才分开,所以不适用 #include<cstdio> #include<cstdlib> #include<iostream> #include<sstream> #include<cstring> using namespace std; const int maxn = 100005; int s[ma

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