【题目链接】
ybt 1231:最小新整数
OpenJudge NOI 4.6 3528:最小新整数
【题目考点】
1. 贪心
【解题思路】
该题与信息学奥赛一本通 1321:【例6.3】删数问题(Noip1994) | 洛谷 P1106 删数问题
是同一问题,具体思路可以参考上一题。
本题的区别点在于:
- 数字长度仅为10位左右
- 所有数字都不为0,也就不用考虑前导0的问题了。
- 有多组数据,注意变量清空。
【题解代码】
解法1:每次找k+1个数中的最小值
#include<bits/stdc++.h>
using namespace std;
#define N 15
int main()
{
int k, t;
char s[N], a[N];
cin >> t;
while(t--)
{
cin >> s >> k;
int an = 0, len = strlen(s), i = 0;
while(i < len)
{
if(k == len-i)//如果剩下的元素个数只有k个,那么都删掉
break;
int mi = i;//求i~i+k的最小值下标
for(int j = i; j <= i+k; ++j)
{
if(s[j] < s[mi])
mi = j;
}
a[++an] = s[mi];
k -= mi - i;//s[i]~s[mi-1]都删掉,删掉了mi-i个元素
i = mi + 1;
}
for(i = 1; i <= an; ++i)
cout << a[i];
cout << endl;
}
return 0;
}
解法2:删掉比后面数字大的数字
#include<bits/stdc++.h>
using namespace std;
#define N 15
int main()
{
int k, t;
char s[N], a[N];
cin >> t;
while(t--)
{
cin >> s >> k;
int an = 0, len = strlen(s), ct = 0;
for(int i = 0; i < len; ++i)
{
while(an > 0 && a[an] > s[i] && ct < k)//a[an]为前一个数 s[i]为后一个数,当a[an]>s[i]时,删除a[an]
{
an--;
ct++;//删除数字个数加1
}
a[++an] = s[i];//无论如何s[i]都会填充进数组a
}
while(ct < k)//删除末尾的k-ct个元素
{
an--;
ct++;
}
for(int i = 1; i <= an; ++i)
cout << a[i];
cout << endl;
}
return 0;
}