题意:ios
你有n我的,对面有m我的(n,m 1e5)每一个人有个攻击和防护,攻击大于等于对方防护能够消灭对方spa
能够都存活或者都被消灭。如今让你安排一些人跟对面的人单挑,要求全歼对面的人并使本身的伤亡数最少code
若是有,输出最小的伤亡数,若是没有这种方案,输出-1.blog
思路:string
维护一个本身的攻击降序和对面的防护降序,而后扫对面的人,每次把攻击大于等于当前对面的防护值的人的防护值加入集合,it
若是能够不死,选择一个防护大于对面当前攻击的最小值,若是谁上都要死,那就选个防护最小值就行了(由于当前攻击打后面的人都够用了)。io
-1的状况很好判断了。被坑了一次set去重。。改了multisetclass
/* *********************************************** Author :devil ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <stack> #include <map> #include <unordered_map> #include <string> #include <time.h> #include <cmath> #include <stdlib.h> #define LL long long #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) #define ou(a) printf("%d\n",a) #define pb push_back #define pii pair<int,int> #define mkp make_pair #define IN freopen("in.txt","r",stdin); #define OUT freopen("out.txt","w",stdout); using namespace std; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int N=1e5+10; int t,n,m; struct wq { int a,b; }a[N],b[N]; bool cmp1(wq a,wq b) { if(a.a!=b.a) return a.a>b.a; return a.b>b.b; } bool cmp2(wq a,wq b) { if(a.b!=b.b) return a.b>b.b; return a.a>b.a; } multiset<int>s; multiset<int>::iterator it; int main() { scanf("%d",&t); for(int cas=1;cas<=t;cas++) { s.clear(); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&a[i].a,&a[i].b); for(int i=1;i<=m;i++) scanf("%d%d",&b[i].a,&b[i].b); printf("Case #%d: ",cas); if(n<m) { printf("-1\n"); continue; } sort(a+1,a+n+1,cmp1); sort(b+1,b+m+1,cmp2); int ans=n-m,p=1; bool flag=1; for(int i=1;i<=m;i++) { while(p<=n&&a[p].a>=b[i].b) s.insert(a[p].b),p++; if(!s.size()) { flag=0; break; } it=s.upper_bound(b[i].a); if(it==s.end()) s.erase(s.begin()); else ans++,s.erase(*it); } if(flag==0) printf("-1\n"); else printf("%d\n",ans); } return 0; }