题目描述
还记得上次新生赛的题目《最小的整数》么,这次题意有少许更改,但是基本题意还是不变的,数据量有所增加,做好心里准备喽。
有一个整数(为n位数),你可以在这个数上去掉任意位,剩下的位置不变,比如123458 ,去掉第3位(从右往左第三位)留下12358,问用这种方法修改这个数直到只剩下一个m位整数,问最小的m位数是多少?我给的数据第一位不会是0。
输入描述
测试数据有多组(大约100组),每组两行数据 ,第一行为两个整数 n,m(0<m<n<1000000),第一个数字为整数的位数,第二个数字为要留下数字的位数。
输出描述
输出最小的m位数。
样例输入
8 7
10001000
5 3
10223
样例输出
1000000
102
贪心+队列优化
数据大了的话,如果在线扫就会超时,开十个队列,分别记录0-9十个数字的位置,先放前n-m+1个数据进去,判断,再每放一个就判断
View Code
#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
char s[1000009];
char ts[1000009];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j;
scanf("%s",s);
queue<int>qq[10];
int min=9;
if(m==1)
{
for(i=0;i<n;i++)
{
if((s[i]-'0')<min)
min=(s[i]-'0');
}
printf("%d\n",min);
continue;
}
int t=n-m,add=0,qi=0;
for(i=0;i<=t;i++)
{
qq[s[i]-'0'].push(i);
}
for(i=1;i<=9;i++)
{
if(qq[i].size()>=1)
{
ts[add]=i+'0';
qi=qq[i].front();
add++;
break;
}
}
for(i=t+1;i<n;i++)
{
qq[s[i]-'0'].push(i);
for(j=0;j<=9;j++)
{
while(qq[j].size()>0&&qq[j].front()<=qi)
{
qq[j].pop();
}
if(qq[j].size()==0)continue;
ts[add]=j+'0';
qi=qq[j].front();
add++;
break;
}
}
ts[add]=0;
printf("%s\n",ts);
}
}