1.题目描述:点击打开链接
2.解题思路:本题利用贪心法,最好边输入边处理,由于需要删除d个数字,即保留n-d个数字。假设变量i来扫描输入的第i个数字(从0开始),那么待填写的数字还有n-i个。令变量k表示第k个已经填写的数字,只有当k<n-d时才能继续填写数字。若k+(n-i)>n-d,即已填写的数字加上等待填写的所有数字大于要保留的数字个数时,需要替换已经填写的数字,此处的贪心策略是:设当前输入的数是c,那么k向前寻找恰好大于c的那个数字的位置p,然后替换掉第p+1位的数字。这种策略可以保证所填的n-d个数字结果是最大的。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; #define maxn 100000+10 char a[maxn]; int n, d, k; int main() { //freopen("test.txt", "r", stdin); while (scanf("%d%d", &n, &d) && n&&d) { getchar(); k = 0; for (int i = 0; i < n; i++) { char c = getchar(); while (k>0 && i - k < d&&a[k] < c)//需要保留n-d个数字,已经填写到第k个,还有n-i个未填写 k--; //若k+(n-i)>n-d(化简后得到i-k<d),说明已经填写的当中有需要删除的,此时选择删除小于c的数字 if (k + d < n)a[++k] = c;//若k<n-d,说明还没有填写够n-d个数字 } a[++k] = '\0'; puts(a + 1); } return 0; }