任务描述
有一个长度为n(n <= 240)的正整数,从中取出s(s < n)个数,使剩余的数保持原来的次序不变,求这个正整数经过删数之后最小是多少。
输入格式
第一行输入n和s
输出格式
输出一个整数
输入样例
178543 4
输出样例
13
得到局部最优解的过程:
要点:
1.存储:动态数组或字符串数组
2.如何删数:c++函数或c直接实现
3.删数依据:出现降序
4.特殊序列:单调递增:每次只删尾元素;【单调递减:每次只删首元素(包含在正常删数过程中)】
5.输出:首元素不为0
代码实现:
c++版:
//#include<vector>
#include<bits/stdc++.h>
using namespace std;
int main()
{
string n;
cin>>n;
int s,flag=0;
cin>>s;
vector<char>A;
//如果是vector<int>A,此处应为 A.push_back(n[i]-'0');
for(int i=0;i<n.size();i++) A.push_back(n[i]);
while(s--)
{
flag=0;
vector<char>:: iterator t=A.begin();
//为了通过迭代器调用vector的库函数erase()删除指定元素
for(int i=0;i<A.size()-1;i++) //A.size()-1,因为有A[i+1]
{
//当出现降序时,删去当前第i个元素
//t和i一样,都是当前元素下标
if(A[i]>A[i+1])
{
A.erase(t);
flag=1;
break;
}
t++; //t随i变化
}
if(flag==0) //如果是一个递增序列,则需要删去最后一个数
A.erase(t);
}
//防止出现前导0
int i=0;
for(i=0;i<A.size();i++) //以第一个不为0的数字开始
{
if(A[i]!='0')
break;
}
//输出
for(int k=i;k<A.size();k++) printf("%c",A[k]);
return 0;
}
c版:
区别仅在于存储和删数方法
#include<stdio.h>
#include<string.h>
char n[200];
int main()
{
int s,flag=0;
scanf("%s %d",n,&s);
int len=strlen(n);
while(s--)
{
int i=0;
flag=0;
for( i=0;i<len-1;i++)
{
if(n[i]>n[i+1])
{
for(int l=i;l<len-1;l++)
{
n[l]=n[l+1];
}
flag=1;
len--;
break;
}
}
if(flag==0)
{
len--;
}
}
//防止出现前导0
int j=0;
for( j=0;j<len;j++)
{
if(n[j]!='0')
break;
}
for(int k=j;k<len;k++)
printf("%c",n[k]);
return 0;
}
vector相关应用:删除指定元素
//通过迭代器调用vector的库函数erase(删除当前第i个元素);insert(在第i个位置插入一个元素)
//方法1:
vector<char>:: iterator t;
for(t=A.begin();t!=A.end();t++)
{
A.erase(t);
}
//方法2:
vector<char>:: iterator t=A.begin();
for(int i=0;i<A.size();i++)
{
A.erase(t);
t++;
}
(1)头文件#include<vector>
(2)创建vector对象,vector<int> A; //int 类型
(3)尾部插入数字:A.push_back(a); //a=1
(4)使用下标访问元素,A[i]
(5)使用迭代器访问元素.
vector::iterator t;
for(t=A.begin();t!=A.end();t++)
(6)插入元素: vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;
(7)删除元素: vec.erase(vec.begin()+2);删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
(8)向量大小:vec.size();
(9)清空:vec.clear();