2020寒假集训排位赛 Meetings题解(排序,二分,思维)

专题链接:https://codeforces.com/group/5yyKg9gx7m/contest/269717/problem/D

思路


先用二分法求出T,再对每只牛按所在的位置排序,记入这时每只牛的排名,然后预测出T时间后每只牛的位置,再次进行排序,将一个方向的所有牛的排名差加起来即为答案

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define lowbit(i) ((i)&(-(i)))
#define ll long long
using namespace std;
int N, L,sum,T;
int ans;
int ra[50001];
struct note
{
	int w;
	double x;//坐标
	int d; // 速度
	int id;
}cow[50001];
bool cam(note a, note b)
{	return a.x < b.x;}
bool check(int mid)
{
	int l=0, r=0;
	for (int i = 1; i <= N; i++)
	{
		int tem = cow[i].x +(int)cow[i].d * mid;
		if (tem <= 0) l++;
		if (tem >= L)r++;
	}
	int tot=0;
	for (int i = 1; i <= l; i++)
		tot += cow[i].w;
	for (int i = 1; i <= r; i++)
		tot += cow[N - i + 1].w;
	if (tot*2 >= sum)
		return 1;
	return 0;
}
int main()
{
	cin >> N >> L;
	for (int i = 1; i <= N; i++)
	{
		int w, x, d;
		scanf("%d%d%d", &w, &x, &d);
		sum += w;
		cow[i].w = w;
		cow[i].x = x;
		cow[i].d = d;
		cow[i].id = i;
	}
	sort(cow + 1, cow + N + 1, cam);
	for (int i = 1; i <= N; i++)
	{
		ra[cow[i].id] = i;
	}
	int l = 0, r = 1e9;
	int mid;
	while (r >= l)//求T
	{
		mid = (r + l) / 2;
		if (check(mid))
		{
			r = mid - 1;
			T = mid;
		}
		else
			l = mid + 1;
	}

    for (int i = 1; i <= N; i++)
	{
		if (cow[i].d == 1)
			cow[i].x += T+0.1;//各位加0.1是为了避免两只牛因并列而漏数的情况
		else
			cow[i].x -= T;
	 }
	sort(cow + 1, cow + N + 1, cam);
	for (int i = 1; i <= N; i++)
		if (cow[i].d == 1)
			ans +=abs(ra[cow[i].id]-i);
	//printf("ans1==%d ans2==%d\n", ans1, ans2);
	printf("%d\n", ans);
	return 0;
}

你可能感兴趣的:(2020寒假集训排位赛 Meetings题解(排序,二分,思维))