您的位置:首页 > 其它

删除游戏

2015-06-03 20:36 239 查看


Description

ACM小组喜欢上了一个无聊的游戏,游戏的过程是输入一个正整数n,去掉n的任意S个数字后,把剩下的数字看作是一个新的整数(去除前导零)。对给定的N和S,寻找一种删数规则使得剩下的数字组成的新数(排列顺序不变)最小。希望你也可以加入这个游戏,编写程序来解决这个问题。

Input

输入包含若干组数据,每组数据一行,为用空格分隔的两个正整数n(2<=length( n )<=2000,length(n)为n的位数)和S(0<S<length(n))。
读入以EOF结束。

Output

对于每个输入数据,输出删除S个数后剩下最小的新数(不要输出前导0)。

Sample Input

5412364 4

Sample Output

123

HINT

#include <stdio.h>

#include <string.h>

#define MIN(a,b) ((a)<(b)?(a):(b))

#define N 2005

char s
;

int d
,top;

int main()

{

int i,j,k,len,cnt,f;

int t,min,max,mid;

while(~scanf("%s%d",&s[1],&k))

{

s[0]=-1,top=0;

d[top++]=0;

len=strlen(s);

for(i=1,cnt=0;cnt<k&&i<=len;)

{

if(top==1||s[i]>=s[d[top-1]])

{

d[top++]=i++;

continue;

}

else

{

min=0,max=top-1;

while(min+1!=max)

{

mid=(min+max)>>1;

if(s[i]<s[d[min]]) max=mid;

else min=mid;

}

t=MIN(k-cnt,top-max);

top-=t,cnt+=t;

}

}

f=1;

for(j=1;j<top&&s[d[j]]=='0';j++);

for(;j<top;j++) printf("%c",s[d[j]]),f=0;

if(f) for(;i<len&&s[i]=='0';i++);

for(;i<len;i++) printf("%c",s[i]),f=0;

if(f) printf("0");

printf("\n");

}

return 0;

}

经典贪心算法题。题目大意,给定一个整数N(位数最多2000)和整数k,在N中删除k个数使得剩下的数组成的整数最小。需要注意的是结果不要输出前导0。

贪心策略为:从高位到低位扫描,若存在递减区间,则将高位删除以消除递减区间,否则从低位删。具体操作时,可以设一个栈来保存从高位起还没删的数。不难发现最后的结果一定是一个不下降序列,由此可以想到用二分来优化。(待研究)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: