COJ1236(删数游戏)

题目链接

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

贪心策略为:从高位到低位扫描,若存在递减区间,则将高位删除以消除递减区间,否则从低位删。具体操作时,可以设一个栈来保存从高位起还没删的数。不难发现最后的结果一定是一个不下降序列,由此可以想到用二分来优化。

View Code
 1 #include <stdio.h>

 2 #include <string.h>

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

 4 #define N 2005

 5 char s[N];

 6 int d[N],top;

 7 int main()

 8 {

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

10     int t,min,max,mid;

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

12     {

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

14         d[top++]=0;

15         len=strlen(s);

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

17         {

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

19             {

20                 d[top++]=i++;

21                 continue;

22             }

23             else

24             {

25                 min=0,max=top-1;

26                 while(min+1!=max)

27                 {

28                     mid=(min+max)>>1;

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

30                     else    min=mid;

31                 }

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

33                 top-=t,cnt+=t;

34             }

35         }

36         f=1;

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

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

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

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

41         if(f)   printf("0");

42         printf("\n");

43     }

44     return 0;

45 }

 

你可能感兴趣的:(游戏)