删数问题(进化)
题目描述
一个集合有如下元素:1是集合元素;若 P 是集合的元素,则 2*P+1,4* P+5 也是集合的元素。
取出此集合中最小的 k 个元素,按从小到大的顺序组合成一个多位数,现要求从中删除 m个数位上的数字,使得剩下的数字最大,编程输出删除前和删除后的多位数字。
注:不存在所有数被删除的情况。
输入格式
只有一行两个整数,分别代表 kk 和 mm。
输出格式
输出为两行两个整数,第一行为删除前的数字,第二行为删除后的数字。
5 4
输出 #1
137915 95
解析:
将题目分成两个部分:(1)生成此序列
(2)删除m个数
(1)生成此序列
根据定义:一个集合有如下元素:1是集合元素;若 P 是集合的元素,则 2*P+1,4* P+5 也是集合的元素。
该序列已经是一个固定的序列
从最小的元素 1 开始:2*1+1=3;4*1+5=9;排序为 1 3 9
第二小元素3:2*3+1=7;4*3+5=17;排序为1 3 7 9 17
第三小元素7:2*7+1=15;4*7+5=33 ;排序为1 3 7 9 15 17 33
这样依次进行下去,可是这里有个问题如例子:输入的是5 排序是1 3 7 9 15 而不是前面生成的1 3 7 9 17
我们可以用STL中的优先队列->priority_queue存放,默认是大根堆,改写一下成小根堆
每次找到最小的哪一个元素 再添加进去由它生成的两个附属元素
(2)删除m个数
可以运用string 里面的erase 【str.erase(起始位置,删除的长度)】,则上面生成的得是string 字符串,运用 to_string将int 类型数据转化成string存放
寻找要删除的数字 即(删数问题)要求删去m个树后,剩下的数要最大,运用循环结构删除,用cnt记录删除次数,达到总次数后跳出循环
代码:
#include <iostream>
#include <bits/stdc++.h>
#include <cstring>
using namespace std;
priority_queue<int,vector<int>,greater<int> >a;
int main()
{
int k,m;
cin>>k>>m;
a.push(1);//1是其中一个元素
string s;
for(int i=1;i<=k;i++) //序列的建立
{
int b=a.top();
s=s+to_string(b);
a.pop();//删除最小的元素
a.push(2*b+1);
a.push(4*b+5);//将b的两个附属元素放入
}
cout<<s<<endl;
int cnt=0;
for(;;)
{
for(int i=0;i<s.size()-1;++i)
{
if(s[i]<s[i+1])
{
cnt++;
s.erase(i,1);
if(cnt==m)
{
cout<<s<<endl;
exit(0);//结束循环
}
break;
}
}
}
return 0;
}
例子:输入数据: 5 4
则输出的序列是 1 3 7 9 15(5个数)
删掉其中的4个数 1、3、7、1、得到 95
浙公网安备 33010602011771号