题意
给出n个数字,消去d个数字,使得剩下的数字最大。
分析
我一开始 就是用 优先队列来进行模拟,直到消去d个数字、
看一下,大神的写法,道理相同,但 代码量 呵呵了。
写糙的方法:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int n, d, s;
struct aa
{
int val;
int id;
bool operator < (const aa& b) const
{
return val > b.val;
}
};
aa a[maxn];
aa vis[maxn];
bool cmp(aa x, aa y)
{
return x.id < y.id;
}
void solve()
{
priority_queue<aa> q;
for(int i = 0; i < n; i++)
{
aa t = a[i];
while(!q.empty() && d){
int _min = q.top().val;
if(_min < t.val){
q.pop();
d--;
}
else
break;
}
q.push(t);
}
memset(vis, 0, sizeof vis);
int j = 0;
while(!q.empty())
{
vis[j++] = q.top();
q.pop();
}
sort(vis, vis+j, cmp);
for(int i = 0; i < j && i < s; i++)
cout << vis[i].val ;
cout << endl;
}
int main()
{
//freopen("in.txt","r",stdin);
while(cin >> n >> d)
{
if(n == 0 && d == 0) break;
getchar();
s = n-d;
for(int i = 0; i < n; i++)
{
char b;
scanf("%c",&b);
a[i].val = b - '0';
a[i].id = i;
}
solve();
}
return 0;
}
抛砖引玉, 看大神的:
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;
}