难度:普及+/提高
题目类型:贪心/模拟
提交次数:3
涉及知识:贪心/BFS/字符串/优先队列
题目描述
描述:
一个集合有如下元素:1是集合元素;若P是集合的元素,则2 * P +1,4*P+5也是集合的元素,
取出此集合中最小的K个元素,按从小到大的顺序组合成一个多位数,现要求从中删除M个数位上的数字,
使得剩下的数字最大,编程输出删除前和删除后的多位数字。
注:不存在所有数被删除的情况
代码:
1 #include<iostream> 2 #include<queue> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 int a[30010]; 7 char c[10000]; 8 string s; 9 priority_queue<int, vector<int>, greater<int> > q; 10 int main(){ 11 int k, m, i = 0; 12 cin>>k>>m; 13 q.push(1); 14 while(!q.empty()){ 15 int t = q.top(); 16 q.push(t*2+1); 17 q.push(t*4+5); 18 q.pop(); 19 a[i++] = t; 20 if(i==k) break; 21 } 22 for(i = 0; i < k; i++){ 23 memset(c, 0, sizeof(c)); 24 sprintf(c, "%d", a[i]); 25 s += c; 26 } 27 cout<<s<<endl; 28 //—————————————————————————————————————— 29 int n = 0; 30 i = 0; 31 while(n<m&&i<s.length()-1){ 32 i++; 33 if(s[i-1]<s[i]){ 34 s.erase(i-1,1); 35 n++; 36 i=0; 37 } 38 } 39 for(i = 0; i < m-n; i++) 40 s.erase(s.length()-1, 1); 41 for(i = 0; i < s.length(); i++){ 42 if(s[i]!='0') { 43 cout<<s.substr(i, s.length()-i); 44 return 0; 45 } 46 } 47 if(i==s.length())cout<<'0'; 48 return 0; 49 }
备注:
过了这道题还是蛮有成就感的。一共分3个重要步骤,一是BFS拓展,二是数组转为字符串,三是贪心解决删数问题。看了题解才想到BFS和优先队列,不过想想也挺显然,跟奶牛那道题差不多。第二个步骤费了些周折,已标出,机智地用了sprintf,一定要加头文件<cstdio>!!!就因为这个,明明我编译可以过,提交就会编译报错!另外我发现srting可以直接和char数组或者单个字符相加,这就很方便了(不过老师不建议这么用,那就先把char数组转成string就好了,导一下的事)。第三部分跟删数问题一样,只不过变成了最大值,所以是找升序。