试题描述
键盘输入一个高精度的正整数N,
去掉其中任意S个数字后剩下的数字按左右次序组成一个新的正整数。
对给定的N和S,寻找一种删数规则使得剩下得数字组成的新数最小。
试题背景 此题出自NOI94
试题分析
这是一道运用贪心策略求解的典型问题。
此题所需处理的数据从表面上看是一个整数。
其实,大家通过对此题得深入分析便知:
本题所给出的高精度正整数在具体做题时将它看作由若干个数字所组成的一串数,
这是求解本题的一个重要突破。这样便建立起了贪心策略的数学描述。
贪心规则:
1、每次删除第一个比下个数大的数字
如 41235
4 1 ...
找到 4 比 1 大,删除 4,得 1235
2、如果数字序列递增排列,则删除最后一个数字
如 1235
序列递增,则删除 5,得 123
// 贪心法_删数问题_源程序
// 调试平台: Microsoft Visual C++ .NET
// 建立工程 Win32控制台应用程序
// greed.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "conio.h"
#include "string.h"
#define strMax 1000
void GreedDelNumber( char str[] , int len , int s )
{
//
//for( int i = 0 ; i < len ; i++ )
// printf( "%c" , str[i] );
//printf( "/n" );
if( s == 0 )
{
char num[ strMax ] = { 0 };
int j = 0;
for( int i = 0 ; i < len ; i++ )
{
if( str[i] != 0 )
num[j++] = str[i];
}
strcpy( str , num );
}
else
{
for( int i = 0 ; i < len ; i++ )
{
int j = i + 1;
while( str[j] == 0 && j < len )
j++;
if( j >= len || str[i] > str[j] )
{
str[i] = 0;
GreedDelNumber( str , len , s - 1 );
return;
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char str[] = "41235";
int s = 2;
printf( "原数为: %s/n" , str );
printf( "长度为: %d/n待删数: %d/n" , strlen( str ) , s );
GreedDelNumber( str , strlen( str ) , s );
printf( "删除后: %s/n" , str );
getch();
return 0;
}