开一个vis[20000]数组进行标记,每次先遍历该区间,查看是否有k个点,如果没有k个点,则将该区间从后往前进行标记直到满足k个点为止。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 10000; const int MAX = 20010; const int INF = 0x3f3f3f3f; struct Segment { int l,r; }s[N]; int vis[MAX]; int save[MAX]; int k,n; bool cmp(Segment a,Segment b) { if(a.r != b.r) { return a.r < b.r; } return a.l < b.l; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&k,&n); for(int i = 0; i < n; i++) { scanf("%d%d",&s[i].l,&s[i].r); if(s[i].l > s[i].r) { swap(s[i].l,s[i].r); } } sort(s,s+n,cmp); memset(vis,0,sizeof(vis)); int sum = 0; for(int i = 0; i < n; i++) { int cnt = 0; for(int j = s[i].l; j <= s[i].r; j++) { if(vis[j+N]) { cnt++; } } if(cnt >= k) { continue; } for(int j = s[i].r; j >= s[i].l && cnt < k; j--) { if(!vis[j+N]) { vis[j+N] = true; save[sum++] = j; cnt++; } } } sort(save,save+sum); printf("%d\n",sum); for(int i = 0; i < sum; i++) { printf("%d\n",save[i]); } if(t) { printf("\n"); } } return 0; }