一:题目
有一个长度为n(n <= 240)的正整数,从中取出k(k < n)个数,使剩余的数保持原来的次序不变,求这个正整数经过删数之后最小是多少。
输入格式:
n和k
输出格式:
一个数字,表示这个正整数经过删数之后的最小值。
输入样例:
178543 4
结尾无空行
输出样例:
13
二:思路
思路:
1.首先贪心的策略是每次最优,那么结果就是最优的
2.那么这道题我们可以每次删除序列中 升序的结尾,重复上述操作k次,这样的话我们就能可以
这个结果的最优解了
解释:因为在一串数中,我们想要其删完某个数后其剩下的值最小,我们总想删除大的数
那么剩下的数肯定要小呀 比如 12345 删除5剩下的数是最小的
3.当然我们也可以删除每次发生降序的时候 就把前一个数删除
三:上码
/**思路:1.首先贪心的策略是每次最优,那么结果就是最优的2.那么这道题我们可以每次删除序列中 升序的结尾,重复上述操作k次,这样的话我们就能可以这个结果的最优解了解释:因为在一串数中,我们想要其删完某个数后其剩下的值最小,我们总想删除大的数那么剩下的数肯定要小呀 比如 12345 删除5剩下的数是最小的 3.当然我们也可以删除每次发生降序的时候 就把前一个数删除
**///100012 2 1#include<bits/stdc++.h>
using namespace std;int main(){string str;int k,flag = 0;vector<char>v;cin >> str >> k;for(int i = 0; i < str.size(); i++){v.push_back(str[i]);} while(k--){int i = 0;flag = 0;vector<char>:: iterator t = v.begin();//这里主要是为了调用 v.erase()的库函数删除元素while(i != v.size()-1){//注意这里的减一 因为下方的v[i+1] 否则会出现段错误if(v[i] > v[i+1]){//如果出现后一个数小于前一个数那么这就是这一趟的递增的终点 v.erase(t);flag = 1;break;}i++;t++;}if(flag == 0){//如果是一个递增序列那么的话就要删除最后一个数 v.erase(t);} } int i = 0;//这么输出是为了防止前置'0'的输出for(int i = 0; i < v.size(); i++) {if(v[i] != '0')break; }int j = i; for( ; j < v.size(); j++){cout << v[j];} }
四:记录失败码
这是第一次做时写的码,测了好多数据,终于测出错误了,然后就退出算法有问题了但还是想记录一下 下方的测试用例可以拿走不谢
/**思路:将输入的数据当成字符串处理并进行排序,输出字符串长度-k个字符
*/#include<bits/stdc++.h>
using namespace std;int main(){int n, k;vector<char>v,v1,v2,v3;int count = 0;cin >> n >> k;;stringstream st;st << n;string str = st.str();for(int i = 0; i < str.size(); i++){v.push_back(str[i]);v2.push_back(str[i]);}sort(v.begin(),v.end());for(int i = 0; i < v.size() - k; i++){v1.push_back(v[i]);}for(int i = 0; i < v2.size(); i++){for(int j = 0; j < v1.size(); j++){if(v2[i] == v1[j] && count < v2.size() - k){v3.push_back(v2[i]);//cout << v2[i]; v1[j] = 'a';//当统计过一次v1容器当中的元素下次就不在输出了99913 2 count++;break;}}}for(int i = 0; i < v3.size(); i++){int temp = v3[i] - '0'; if(temp != 0)cout << temp;}} //测试用例
//1378541 4//378541 4//1378541 6//11378541 6//11378541 5//378541 4//99913 2//100012 1//这个测试用例推翻算法 正确结果应是 12 上方代码输出10001
// 错误原因:他存的时候将10001存进去了v1,那么就永远得不到12