二分答案,但是这里的判断不同于一般的二分。
分别将cows和cowc按照s和c排序。
我的代码里check函数的返回值含义如下:
-1 直接输出,不可能满足条件了
0 这种方案是满足条件的,可以把中位数调大试试
1 这种方案是不满足的,但是把中位数调大就有可能满足了(否则不可能满足)
2 这种方案是不满足的,但是把中位数调小就有可能满足了(否则不可能满足)
还是不会用cpp,用了switch语句却没写break,导致纠结了好长时间。
终于给家里台式机装上Ubuntu了,才发现NOI Linux就是害人用的啊。
参考代码
# include <cstdio> # include <iostream> # include <cstring> # include <algorithm> using namespace std; const int maxN=100005; struct Node{ int c,s,id; }; int n,m,tot; Node cows[maxN],cowc[maxN]; bool cmps(Node a,Node b) { return a.s<b.s; } bool cmpc(Node a,Node b) { return a.c<b.c; } int check(int limit) { int left=0,right=0,all=cows[limit].c; for (int i=0;i<n;i++){ if ((cowc[i].id<limit)&&(all+cowc[i].c<=tot)&&(left<m/2)){ all+=cowc[i].c;left++; } else if ((cowc[i].id>limit)&&(all+cowc[i].c<=tot)&&(right<m/2)){ all+=cowc[i].c;right++; } } if ((left<m/2)&&(right<m/2)) return -1; else if (left<m/2) return 1; else if (right<m/2) return 2; else return 0; } int main() { scanf("%d%d%d",&m,&n,&tot); for (int i=0;i<n;i++) scanf("%d%d",&cows[i].s,&cows[i].c); sort(cows,cows+n,cmps); for (int i=0;i<n;i++) cows[i].id=i; memcpy(cowc,cows,sizeof(cows)); sort(cowc,cowc+n,cmpc); int l=1,r=n,ans=-1; while (l<=r){ int mid=(l+r)>>1; switch (check(mid)){ case -1: { printf("-1\n"); return 0; } case 0: { ans=cows[mid].s; l=mid+1; break; } case 1: { l=mid+1; break;} case 2: { r=mid-1; } } } if (ans>=0) printf("%d\n",ans); else printf("-1\n"); return 0; }