分析:使用优先队列.
以next为优先级,小的先出队
读入数据后排序,初始化队列第一个元素(0,a[0],0)
每次出队一个元素,入队(sum,sum+a[nextid+1],nextid+1),(next,next+a[nextid+1],nextid+1),即是否加上a[nextid+1]都考虑进去了。
这样每次新加入的元素都是下一个最小的(next),进行m次就得到了第m小。
#include<iostream> #include<queue> #include<algorithm> using namespace std; struct A { A(){} A(int s,int n,int ni):sum(s),next(n),nextid(ni) { } bool operator<(const A& a)const { return this->next>a.next; } int sum; //当前和 int next; //加入下个元素和 int nextid; //下个元素id }; int a[10010]; int n,m; int Run() { priority_queue<A> q; A tmp; int cnt; q.push(A(0,a[0],0)); cnt=0; while(!q.empty()) { tmp=q.top(); q.pop(); if(tmp.nextid>=n) //超出范围,却多计算了a[n],设置的结尾值 continue; q.push(A(tmp.sum,tmp.sum+a[tmp.nextid+1],tmp.nextid+1)); q.push(A(tmp.next,tmp.next+a[tmp.nextid+1],tmp.nextid+1)); cnt++; if(cnt==m) return tmp.next; } } int main() { int T,i,c; scanf("%d",&T); c=0; while(T--) { scanf("%d%d",&n,&m); for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); a[n]=0; printf("Case #%d: %d\n",++c,Run()); } return 0; }
时间: 2024-11-02 19:12:19