#### Example 30 Censoring problem

**Problem description**

Enter a high-precision positive integer num (Num no more than 250 bits) from the keyboard. After removing s digits, the remaining digits will form a new positive integer according to the original order. Write a program, for a given num and s, to find a solution, so that the remaining number of new numbers minimum.

**Input format**

Num (high precision positive integer) and S (number of digits to delete).

**Output format**

The last remaining decimal.

**sample input **

51428397

5

**sample output **

123

##### (1) Programming ideas.

Because the keyboard input is a high-precision positive integer num (Num does not exceed 250 bits), so the string array is used for storage.

In order to approach the target as much as possible, the greedy strategy is: in each step, always select a number which makes the remaining number the smallest to delete, that is, search by high order to low order, if each number increases, then delete the last number, otherwise delete the first character of the first decreasing interval. Then go back to the beginning of the string and delete the next number according to the above rules. Repeat the above process s times, the remaining number string is the solution of the problem.

That is to say, when greedy algorithm is used to solve the censoring problem, the greedy strategy of nearest descent point priority is adopted: x1

In addition, after deleting the s bit according to this method, we should pay attention to remove the leading 0 that may exist in the result.

##### (2) Source program.

#include

#include

int main()

{

char num[251]={‘\0’};

int s,i,j;

scanf(“%s”,num);

scanf(“%d”,&s);

while (s>0) // Cycle s times and delete one number at a time

{

i=0; // Search the number to be deleted from the beginning after each deletion

while (num[i]!=’\0′ && num[i]<=num[i+1])

i++;

for(j=i;j

num[j]=num[j+1]; // Delete the number at position i

s–;

}

i=0;

while(num[i]==’0′) i++; // Processing leading 0

if (num[i]==’\0′) printf(“0\n”);

else printf(“%s\n”,&num[i]);

return 0;

}

#### Exercise 30

##### 30-1 Deletion problem (enhanced version)

This question is selected from Luogu question bank（ https://www.luogu.org/problem/ P1323）

**Title Description**

A set has the following elements: 1; If P is the element of the set, then 2 * P + 1 and 4 * P + 5 are also the elements of the set. Take out the smallest k elements in the set and combine them into a multi digit number in the order from small to large. Now it is required to delete the number on M digits to make the remaining number maximum. The program outputs the multi digit numbers before and after deletion.

Note: all numbers are not deleted

**Input format**

Input only one line, K, m values, K, m are less than or equal to 30000.

**Output format**

The output is two lines, the first line is the number before deletion, and the second line is the number after deletion.

**sample input **

5 4

**sample output **

137915

95

(1) Programming ideas.

This problem is an enhanced version of example 30, mainly to generate the number of digits to be deleted. The number composed of multi bits comes from a given set. For the generation method of the first 30000 elements in the set, please refer to the programming ideas in “100 cases of C language programming (14): ugly numbers”.

After generating the multi bit number, delete the number according to the greedy strategy of example 30.

(2) Source program.

#include

int main()

{

int H[30001];

char num[300000]={‘\0’},temp[10];

int k,m,i,j,t,cnt,len;

scanf(“%d%d”,&k,&m);

int p2,p3,min;

H[1]=1;

p2=p3=1;

i=1;

while(i

{

min=2*H[p2]+1;

if (min>4*H[p3]+5) min=4*H[p3]+5;

H[++i]=min;

if(H[i]==2*H[p2]+1) p2++;

if(H[i]==4*H[p3]+5) p3++;

}

len=0;

for (i=1;i<=k;i++)

{

t=H[i]; cnt=0;

while (t!=0)

{

temp[cnt++]=t%10+’0′;

t/=10;

}

for (j=cnt-1;j>=0;j–)

num[len++]=temp[j];

}

num[len]=’\0′;

printf(“%s\n”,num);

cnt=0; // Number of deleted numbers

i=1, j=0; // Subscript I is used to traverse the string and subscript j is used to save the result string

while (i

{

if (num[i]<=num[j]) // Do not delete, keep in the result string

num[++j]=num[i++];

else

{

j–,cnt++; // Delete the character indicated by subscript j in the result string

if (j==-1) num[++j]=num[i++];

}

}

while (i

num[++j]=’\0′;

printf(“%s\n”,num);

return 0;

}

##### 30-2 Student grouping

This question is selected from Luogu question bank（ https://www.luogu.org/problem/ P1109）

**Title Description**

There are n groups of students, give the number of students in each group at the beginning, and then give the upper bound R and lower bound L (L ≤ R) of the number of students in each group. Each time you can choose a student in a group and arrange him to another group, ask at least how many times to make the number of students in N groups in [l, R].

**Input format**

In the first line, an integer n represents the number of student groups; n≤50

In the second line, n integers represent the number of students in each group;

In the third line, two integers L and R represent the lower and upper bounds.

**Output format**

A number that represents the minimum number of exchanges. If the problem condition cannot be met, output – 1.

**sample input **

2

10 20

10 15

**sample output **

5

(1) Programming ideas.

When inputting the number of N groups of students in each group, sum the total number of studentsWhen n * l (denotes n groups, each group has r people at most, the total number exceeds, and some students cannot be put into a group), output “- 1”.

If the conditions can be met, the first step is to find out how many people need to be transferred out of each group whose number exceeds the upper limit, and use a to accumulate; Then find out how many people are needed to make up for the missing number in each group whose number is less than the lower limit, and use B to accumulate. Then, the best way is to let a make up for B, so who is bigger is the least number of times.

(2) Source program.

#include

#include

int main()

{

int num[51],n,i,sum,a,b,l,r;

scanf(“%d”,&n);

for (sum=0,i=0;i

{

scanf(“%d”,&num[i]);

sum+=num[i];

}

scanf(“%d%d”,&l,&r);

if (sumN * r) / / the total number is less than or more than

printf(“-1\n”);

else

{

a=0; b=0;

for (i=0;i

{

if (num[i]>r) a+=num[i]-r;

if (num[i]

}

printf(“%d\n”,a>b?a:b);

}

return 0;

}

##### 30-3 stay at home and watch TV

**Problem description**

Assuming you already know the schedule of all the TV programs you like to watch, would you arrange to watch as many complete programs as possible?

**Input format**

The input data contains multiple test cases. The first line of each test case has only one integer n (n < = 100), which represents the total number of programs you like to watch. Then there are n lines of data, each line contains two data ti_ s,Ti_ E (1 < = I < = n), respectively, represents the start and end time of the ith program. In order to simplify the problem, each time is represented by a positive integer. N = 0 indicates the end of input and no processing.

**Output format**

For each test case, the number of TV programs that can be seen completely is output, and the output of each test case occupies one line.

**sample input **

12

1 3

3 4

0 7

3 8

15 19

15 20

10 15

8 18

6 12

5 10

4 14

2 9

0

**sample output **

5

(1) Programming ideas.

Define a structure

struct showtime

{

int begin;

int end;

};

Used to save the start time and end time of a TV program. Define the structure array show [101] to save the input TV program.

The greedy method is used to solve the problem. Arrange TV programs (i.e. structure array show) according to the end time from small to large (if the end time is the same, then according to the start time from large to small).

First, let last = show [0]. End, because the end time of the first element must be the earliest. Then traverse the elements of the array from left to right. If the start time of the current element is greater than last, you can watch a complete program, count, and modify last to make it equal to the end time of the current element. Until all elements of the array are traversed.

(2) Source program.

#include

#include

using namespace std;

struct showtime

{

int begin;

int end;

};

bool cmp(showtime a ,showtime b)

{

if(a.end != b.end)

return a.end < b.end;

else

return a.begin > b.begin;

}

int main()

{

showtime show[101];

int n,i,cnt,lastend;

while (scanf(“%d”,&n) && n!=0)

{

for (i = 0;i

{

scanf(“%d%d”,&show[i].begin,&show[i].end);

}

sort(show,show+n,cmp);

cnt = 1;

lastend = show[0].end;

for (i = 0;i < n ;i++)

{

if(lastend <= show[i].begin)

{

cnt++;

lastend = show[i].end;

}

}

printf(“%d\n”,cnt);

}

return 0;

}