ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2020.2.19GDUT寒假训练排位赛1-D

2020-02-24 18:07:31  阅读:353  来源: 互联网

标签:include 头牛 排位赛 相遇 2020.2 谷仓 几头 19GDUT 奶牛


D — Circular Dance

题目大意:

两个谷仓位于一维数轴上的位置0和L(1≤L≤109)。也有N头牛(1≤N≤5*104)在不同的地点在数轴上的。每头奶牛i最初位于xi的某个位置,以每秒1单位的速度向正或负方向移动,用整数di表示,di为1或- 1。每头奶牛的体重wi也在范围[1,103]内。所有的奶牛总是以恒定的速度移动,直到下列事件之一发生:如果奶牛i到达谷仓,那么奶牛i停止移动。当两头牛i和j占据了同一个地方,而那个地方不是谷仓时,在这种情况下,奶牛i与j速度交换。注意,奶牛可能会在非整数的点相遇。
当进入谷仓的所有牛的重量之和至少是所有牛的重量之和的一半时,所用时间记为T。请确定在时间0…T范围内(包括时间T),两对牛的总相遇次数。
输入
第一行包含两个以空格分隔的整数N和L。
接下来的N行分别包含三个以空格分隔的整数wi、xi和di。所有的位置xi都是不同的,并且满足0<xi<L.
输出
只有一行,相遇对数。
在这里插入图片描述

题目分析:

两头奶牛相遇时交换速度可以看作互相穿过交换体重了,所以向左的有几头牛,最后就有几头牛归向0,向右的有几头牛,最后就有几头牛归向L。所以,对位置排序的奶牛,如果有n头牛,x头牛向左走,y头牛向右走。那么前x个重量一定会归向0位置,后y个重量会归为L位置。离谷仓最近的奶牛肯定先进,就可以算出时间T了。算出在无限时间的相遇对数和T内未相遇的对数,两个数值相减即答案。

代码实现:

#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;

struct cow
{
	int w,x,d,t;
	double x1;
}a[50010],b[50010],c[50010];

bool cmp1(cow x,cow y)
{
	if (x.x==y.x) return x.d>y.d;
	return x.x<y.x;
}

bool cmp2(cow x,cow y)
{
	return x.t<y.t;
}

bool cmp3(cow x,cow y)
{
	return x.x1<y.x1;
}

int main()
{
    int n,len;
    int ans = 0, ans0 = 0;
    int sum = 0, sum_wight = 0, wight = 0;
    int m_i = 0, s = 0;
    int time = 0;
    int l,r;
	scanf("%d%d",&n,&len);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d%d", &a[i].w, &a[i].x, &a[i].d);
		sum_wight += a[i].w;
	}
	sort(a+1,a+n+1,cmp1);
	for(int i=1; i<=n; i++){	//无限时间相遇次数ans
        if(a[i].d==1) sum++;
        else ans += sum;
	}
	for(int i=1; i<=n; i++)	//为了找出先进入谷仓的重量
	{
		if(a[i].d==-1) b[i].t = a[i].x;
		else b[i].t = len-a[i].x;
		b[i].x = a[i].x;
		b[i].d = a[i].d;
	}
	sort(b+1,b+n+1,cmp2);	//排序,越靠前越先进入谷仓
	l = 1;
	r = n;
	for(int i=1; i<=n; i++)	//算出时间T,即time
	{
		if(b[i].d==1)
		{
			wight += a[r].w;
			r--;
		}
		else
		{
			wight += a[l].w;
			l++;
		}
		if(wight*2>=sum_wight)
		{
			m_i = i+1;
			time = b[i].t;
			break;
		}
	}
	for(int i=m_i; i<=n; i++)
    {
        if (b[i].t>time)
        {
            s++;
            if(b[i].d==1) c[s].x1 = b[i].x+time+0.1;	//错开相遇点
            else c[s].x1 = b[i].x-time-0.1;
            c[s].d = b[i].d;
        }
    }
	sort(c+1,c+s+1,cmp3);
	sum = 0;
	for(int i=1; i<=s; i++){
        if(c[i].d==1) sum++;
        else ans0 += sum;
	}
	printf("%d\n",ans-ans0);
	return 0;
}

最后希望路过的dl给予改进建议!

csdn_xieql 发布了28 篇原创文章 · 获赞 0 · 访问量 467 私信 关注

标签:include,头牛,排位赛,相遇,2020.2,谷仓,几头,19GDUT,奶牛
来源: https://blog.csdn.net/csdn_xieql/article/details/104441495

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有