题意:给你一个数m,有多少优惠券,给个n,主角想用多少优惠券。然后接下来时m行,每行两个数,那张优惠券的优惠区间a,b(在a号货物到b号货物之间的所有都可以优惠)
问你,能不能用k张优惠券,是他的优惠区间重叠的部分最大。
今天第一次看优先队列,居然还有这么神奇的东西,omg,太强了
思路就是排序,然后用优先队列乱搞一下。。。
接下来给出代码
#include <iostream> #include <queue> #include <algorithm> #include <stdio.h> using namespace std; const int Maxn = 2147483647; struct Node{ int l,r; int i; }node[300010]; bool cmp( const Node &a,const Node &b ){ return ( a.l == b.l ? a.r < b.r:a.l < b.l ); } int main(){ int m,n; scanf("%d%d",&m,&n); for( int i = 1; i <= m; i++ ){ scanf("%d%d",&node[i].l,&node[i].r); node[i].i = i; } sort( node+1,node+1+m,cmp ); priority_queue<int,vector<int>,greater<int> > q; int inf = -Maxn; int x; int l,r; for( int i = 1; i <= m; i++ ){ x = node[i].l; q.push( node[i].r ); while( q.top() < x || q.size() > n ){ q.pop(); } if( q.size() == n ){ if( inf < q.top() - x + 1 ){ inf = q.top() - x + 1; l = x,r = q.top(); } } } if( inf == - Maxn ){ cout << '0' << endl; for( int i = 1; i <= n; i++ ){ printf( "%d ",i ); } printf( "\n" ); exit(0); }else{ cout << inf << endl; for( int i = 1; i <= m; i++ ){ if( node[i].l <= l && node[i].r >= r ){ printf("%d ",node[i].i); n--; if( n == 0 ){ cout << '\n'; exit(0); } } } } }