妙用队列优化——校赛题

最小的整数(HD版)

时间限制 : 1000 ms    内存限制 : 100 MB

提交次数 : 60    通过次数 : 5

题目描述

还记得上次新生赛的题目《最小的整数》么,这次题意有少许更改,但是基本题意还是不变的,数据量有所增加,做好心里准备喽。

有一个整数(为n位数),你可以在这个数上去掉任意位,剩下的位置不变,比如123458 ,去掉第3位(从右往左第三位)留下12358,问用这种方法修改这个数直到只剩下一个m位整数,问最小的m位数是多少?我给的数据第一位不会是0。

输入描述

 测试数据有多组(大约100组),每组两行数据 ,第一行为两个整数 n,m(0<m<n<1000000),第一个数字为整数的位数,第二个数字为要留下数字的位数。

输出描述

输出最小的m位数。

样例输入

8 7

10001000

5 3

10223

样例输出

1000000

102

贪心+队列优化

数据小的时候的解题报告:

http://www.cnblogs.com/huhuuu/archive/2011/11/09/2243635.html

数据大了的话,如果在线扫就会超时,开十个队列,分别记录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);
}
}



你可能感兴趣的:(优化)