【思路、优化】UVa 11491

Juliano is a fan of the TV show Erasing and Winning, where participants are selected in a draw and receive money for taking part in the show.

In the show, the presenter writes a number of N digits in a board. The participant must then erase exactly D digits from the number in the board; the number formed by the remaining digits is the value of the money prize for the participant.

Juliano was at last selected to take part in the show, and asked you to write a program that, given the number the presenter wrote in the board, and the number of digits Juliano must erase, determines the highest value of the prize he can win.

Input

The input contains several test cases. The first line of a test case contains two integers N and D (1 ≤ D < N ≤ 105 ) indicating respectively the number of digits of the number the presenter wrote in the board and the number of digits that must be erased. The next line contains the number the presenter wrote; the number does not start with a zero. The end of input is indicated by a line containing only two zeros, separated by a space.

Output

For each test case in the input your program must produce one single line in the output, containing the highest prize Juliano can win.

Sample Input

4 2

3759

6 3

123123

7 4

1000000

0 0

Sample Output

79

323

100

题意:题目很好理解,给你一串数,要求消去其中的D个数,使剩下的数最大。

分析:TLE了很长时间一直优化不成功。后来才知道思路就很暴力。下面给两个思路,可以都尝试一下;

①首先记录每个数字0~9出现的位置,然后从9~0开始循环,从后往前依次将数字放到相应位置,期间注意一旦放置(N-D)个数字后立即退出循环。最后扫一遍字符串,没有数字的位置不输出。这样复杂度为0(n*10);

②第二个思路是网上的思路,先从头扫描,一旦发现digit[i]<digit[j]&&(i<j),就从i处向前将小于digit[j]的数删掉;

首先看了思路之后自己尝试写了一下,可惜优化的还是不好(读者也可以先根据思路尝试写下,独立AC更有成就感吖~)。

后来看了题解,发现可以用list实现,list的erase与iter的灵活运用很有用处。

下附代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<list>
 6 using namespace std;
 7 int d, n, alnum[12];
 8 char num[100010];
 9 
10 void solve()
11 {
12     list<int> ans;
13     ans.push_back(10);
14     for(int i = 0; i < n; i++)
15     {
16         ans.push_back(num[i]-'0');
17     }
18     ans.push_back(10);
19 
20     list<int>::iterator head, tail, iter;
21     head = ans.begin(); head++;
22     tail = ans.begin();
23     int cnt = 0;
24     while(cnt < d)
25     {
26         if(*head > *tail)
27         {
28             ans.erase(tail);
29             head--;
30             tail = head;
31             head++;
32 
33             cnt++;
34         }
35         else
36         {
37             head++;
38             tail++;
39         }
40     }
41     ans.pop_back();
42     for(iter = ans.begin(); iter != ans.end(); iter++)
43     {
44         if(*iter == 10) continue;
45         printf("%d", *iter);
46     }
47     printf("
");
48 }
49 
50 int main()
51 {
52     //freopen("in.txt", "r", stdin);
53     while(scanf("%d%d", &n, &d))
54     {
55         if(!n && !d) break;
56         scanf("%s", num);
57         solve();
58     }
59     return 0;
60 }
View Code
原文地址:https://www.cnblogs.com/LLGemini/p/4352786.html