题目链接:点击打开链接
题目大意:邀请n个人去旅游,给出每个人同意邀请时对人数的限制条件:最小人数和最大人数,一旦接收邀请就不会再退出,求一个序列,在这个序列中可以邀请到最多的人去旅游。
首先对n个人的最小人数限制由小到大排序,记录当前已经接受邀请的人数,然后将满足最小人数的人加入优先队列,优先队列按照最大人数由小到大排列,每次吐出的都是最大人数限制的最小值,如果当前的人数小于等于最大的人数就可以邀请到,否则就邀请不到。每当接受邀请的人数增加,就循环一次,直到所有人都遍历完。
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std ;
struct node{
int s , e , id ;
bool operator < (node a) const {
return e > a.e ;
}
}p[100010] , q ;
priority_queue <node> que ;
int vis[100010] ;
vector<int> vec ;
int cmp(node a,node b) {
return a.s < b.s ;
}
int main() {
int t , n , i , j , num ;
scanf("%d", &t) ;
while( t-- ) {
while( !que.empty() ) que.pop() ;
memset(vis,0,sizeof(vis)) ;
vec.clear() ;
scanf("%d", &n) ;
for(i = 0 ; i < n ; i++) {
scanf("%d", &p[i].s) ;
p[i].id = i+1 ;
}
for(i = 0 ; i < n ; i++)
scanf("%d", &p[i].e) ;
sort(p,p+n,cmp) ;
num = 0 ; i = 0 ;
for(j = 0 ; j < n ; j++) {
while( i < n ) {
if( p[i].s <= num ) {
que.push(p[i]) ;
i++ ;
}
else break ;
}
while( !que.empty() ) {
if( que.top().e >= num ) {
vec.push_back( que.top().id ) ;
vis[ que.top().id ] = 1 ;
que.pop() ;
num++ ;
break ;
}
else
que.pop() ;
}
}
int cnt = 0 ;
printf("%d\n", vec.size()) ;
for(i = 0 ; i < vec.size() ; i++) {
cnt++ ;
if( cnt == n )
printf("%d\n", vec[i]) ;
else
printf("%d ", vec[i]) ;
}
for(i = 1 ; i <= n ; i++) {
if( vis[i] ) continue ;
cnt++ ;
if( cnt == n )
printf("%d\n", i) ;
else
printf("%d ", i) ;
}
}
return 0 ;
}