洛谷P1323
https://www.luogu.com.cn/problem/P1323
题意:
思路:
取出前k小个,每次可以取出当前最小的值然后进行拓展,可以使用优先队列,删除数字使得剩余保持最大,那么每次发现当前数字比前一个数字大,就可以删去前一个数字,可以使用栈来实现,若是使删除后的数字变小,每次发现当前数字比前一个数字小,就需要删除前一个数字,一样使用栈完成
题解:
#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
#define deb(x) cout<<#x<<" "<<x<<endl;
using namespace std;
typedef pair<int, int> pii;
bool checkP2(int n) { return n > 0 and (n & (n - 1)) == 0; };
int k, m;
void solve() {
scanf("%lld%lld", &k, &m);
priority_queue<int, vector<int>, greater<int>>q;
vector<int> v;
q.push(1);
while (v.size() < k) {
auto t = q.top();
q.pop();
v.eb(t);
q.push(2 * t + 1);
q.push(t * 4 + 5);
}
string s = "";
for(auto i:v) s+=to_string(i);
int n = s.size() - 1;
stack<int> st;
for (int i = 0;i <= n;i++) {
int x = s[i] - '0';
while(st.size() and st.top()<x and m){
st.pop();
m--;
}
st.push(x);
}
string res = "";
while (st.size()) res += st.top() + '0', st.pop();
while (res.size() > 1 and res.back() == '0') res.pop_back();
reverse(all(res));
cout<<s<<endl;
for (int i = 0;i < min((int)res.size(), n - m + 1);i++) {
printf("%c", res[i]);
}
}
signed main() {
//int _; scanf("%lld",&_); while (_--)
solve();
return 0;
}
删除后使得数字变成最小
char s[300];
void solve() {
int k;
scanf("%s", s + 1);
scanf("%lld", &k);
int n = strlen(s + 1);
stack<int> st;
int cur = n - k;
for (int i = 1;i <= n;i++) {
int x = s[i] - '0';
if (st.empty()) st.push(x);
else {
while (st.size() and x < st.top() and k) {
st.pop();
k--;
}
st.push(x);
}
}
string res = "";
while (st.size()) res += st.top() + '0', st.pop();
while (res.back() == '0' and res.size() > 1) res.pop_back();
reverse(all(res));
for (int i = 0;i < min(cur, (int)res.size());i++) {
printf("%c", res[i]);
}
}