二分答案,但是这里的判断不同于一般的二分。
分别将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;
}