题意:对给定m位数删除其中n位,不改变剩余数字排列,求剩余数字组成的最小数。
思路:选m - n个数 RMQ求最小值 t数组求最小值第一次出现的位置 左右区间随之改变
wa了两次 没特判 m = n 的情况 / t数组存了最小值最后一次出现的位置(25行没用小于等于号用了小于号)
1 #include<map>
2 #include<set>
3 #include<cmath>
4 #include<cstdio>
5 #include<vector>
6 #include<cstring>
7 #include<cstdlib>
8 #include<iostream>
9 #include<algorithm>
10 using namespace std;
11 const int N = 20;
12 int n, q, len;
13 int a[1007],b[1007], f[1007][N], t[1007][N];
14 void RMQ()
15 {
16 for (int i = 1; i <= len; i++)
17 {
18 f[i][0] = a[i];
19 t[i][0] = i;
20 }
21 for (int j = 1; (1 << j) <= len; j++)
22 {
23 for (int i = 1; i + (1<<j) - 1 <= len; i++)
24 {
25 if(f[i][j - 1] <= f[i + (1 << (j - 1))][j - 1])
26 {
27 f[i][j] = f[i][j - 1];
28 t[i][j] = t[i][j - 1];
29 }
30 else
31 {
32 f[i][j] = f[i + (1 << (j - 1))][j - 1];
33 t[i][j] = t[i + (1 << (j - 1))][j - 1];
34 }
35 }
36 }
37 }
38 int main()
39 {
40 string s;
41 while (cin >> s)
42 {
43 cin >> n;
44 len = s.size();
45 if (n == len) cout << "0" << endl;
46 else
47 {
48 for (int i = 0; i < len; i++) a[i + 1] = s[i] - '0';
49 RMQ();
50 int k = len - n;
51 int l = 1, r = len - k + 1;
52 for (int i = 1; i <= k; i++)
53 {
54 int s = 0;
55 while (1 << (s + 1) < (r - l + 1)) s++;
56 if (f[l][s] <= f[r - (1 << s) + 1][s])
57 {
58 b[i] = f[l][s];
59 l = t[l][s] + 1;
60 r++;
61 }
62 else
63 {
64 b[i] = f[r - (1 << s) + 1][s];
65 l = t[r - (1 << s) + 1][s] + 1;
66 r++;
67 }
68 }
69 int i = 1;
70 for (i = 1; i < k; i++)
71 {
72 if (b[i] != 0) break;
73 }
74 for (int j = i; j <= k; j++) cout << b[j];
75 cout << endl;
76 }
77
78 }
79
80 }
来源:https://www.cnblogs.com/hfcdyp/p/12424105.html