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');
}