1323 删数问题(加强版)

难度:普及+/提高

题目类型:贪心/模拟

提交次数: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就好了,导一下的事)。第三部分跟删数问题一样,只不过变成了最大值,所以是找升序。

posted @ 2016-08-24 20:39  timeaftertime  阅读(472)  评论(0编辑  收藏  举报