题意:
已知一个集合S 由S的任意子集作为因子 可构造出一个数字 求 这些构造出的数字中第k大的数字是多少
思路:
拿到这题就被“数字不是很多而且比较连续暴力枚举就好”这个思路迷惑了 果断TLE…
跪了一次后想到通过bfs构造可取 这时用了queue维护bfs 用priority_queue维护答案(大顶堆 内部最多k个数字) 用set判重复(5*2=2*5) 写法不优秀还是TLE…
之后想到了2个剪枝 1.利用S单调性减少判重 2.利用新搜出结果的暂时单调性减少搜索数量
第三次提交终于AC了… (我知道这题让我做水了…)
代码:
/*
ID: housera1
PROG: humble
LANG: C++
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<set>
#include<cstdlib>
#include<ctime>
using namespace std;
typedef long long ll;
struct node
{
ll val;
int pos;
}now;
int n,m;
ll p[110];
queue<node> bf;
priority_queue<ll> qu;
void bfs()
{
int i,amt;
ll tmp,val;
now.val=1,now.pos=1;
bf.push(now);
while(!bf.empty())
{
now=bf.front();
val=now.val;
bf.pop();
for(i=now.pos;i<=n;i++) //剪枝1
{
tmp=val*p[i];
if(tmp!=1LL)
{
amt=qu.size();
if(amt<m)
{
qu.push(tmp);
now.val=tmp;
now.pos=i;
bf.push(now);
}
else if(amt==m&&qu.top()>tmp)
{
qu.pop();
qu.push(tmp);
now.val=tmp;
now.pos=i;
bf.push(now);
}
else break; //剪枝2
}
}
}
}
int main(){
int Debug=0;
if(!Debug){
freopen("humble.in","r",stdin);
freopen("humble.out","w",stdout);
}
int i,j;
//clock_t bg=clock();
while(!qu.empty()) qu.pop();
while(!bf.empty()) bf.pop();
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++) scanf("%lld",&p[i]);
sort(p+1,p+1+n);
bfs();
printf("%lld\n",qu.top());
//clock_t fi=clock();
//printf("time is %d\n",fi-bg);
return 0;
}