信息学奥赛一本通(1321:【例6.3】删数问题(Noip1994))

1321:【例6.3】删数问题(Noip1994)


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 18133     通过数: 6280

【题目描述】

输入一个高精度的正整数n,去掉其中任意s个数字后剩下的数字按原左右次序组成一个新的正整数。编程对给定的n和s,寻找一种方案使得剩下的数字组成的新数最小。

输出新的正整数。(n不超过240位)

输入数据均不需判错。

【输入】

n

s

【输出】

最后剩下的最小数。

【输入样例】

175438
4

【输出样例】

13

【分析】

        试题中正整数N的有效位数为240位,故必须用字符串来模拟。那么如何决定哪s 位被删除呢? 是不是最大的 s 个数字呢? 显然不是,大家很容易举出一些反例。为了尽可能逼近目标,我们选取的贪心策略为:每一步总是选择一个使剩下的数最小的数字删去,即按高位到低位的顺序搜索,若各位数字递增,则删除最后一个数字,否则删除第一个递减区间的首字符,这样删一位便形成了一个新数字串。然后回到串首,按上述规则再删下一个数字。重复以上过程s 次为止,剩下的数字串便是问题的解了。

【参考代码】

#include <stdio.h> 
#include <string.h> 
void del(char x[],int p) 
{ 
    int i,m; 
    m=strlen(x); 
    for(i=p;i<m;i++) 
        x[i]=x[i+1]; 
    x[m-1]='\0'; 
} 
int main()
{ 
    char n[241]={'\0'}; 
    int i,m,flag,s,count=0; 
    scanf("%s %d",n,&s); 
	while(count<s) 
    {
    	flag=0;
        m=strlen(n);
        for(i=0;i<m-1;i++)
        {
        	if(n[i]>n[i+1])
           	{ 
               del(n,i); 
               flag=1; 
               break; 
           	}
       	}
        if(flag==0) 
           n[m-1]='\0'; 
        count++;         
    }
    flag=0;  
    for(i=0;n[i]!='\0';i++)           // 删去串首可能产生的无用的零  
    { 
        if(flag==1) 
           printf("%c",n[i]); 
        else if(n[i]!='0') 
        { 
            flag=1; 
            printf("%c",n[i]); 
        }
    } 
    putchar('\n'); 
}

http://ybt.ssoier.cn:8088/problem_show.php?pid=1321

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值