第十一届山东省大学生程序设计竞赛(热身赛)C-Mika with Cherry Cake(贪心)

该博客讨论了一个二维平面上的数学问题,其中一个人物a试图从原点出发追上多个沿着固定方向移动的商人。题目分析了追上商人的条件,指出只有当商人移动距离为2或4时才可能被追上,并且给出了如何优化路径以追到最多商人的策略。通过遍历所有商人并考虑它们的位置和移动方向,可以计算出a最多能获得的樱桃数量。博客中还涉及到了排序优化以提高效率。
摘要由CSDN通过智能技术生成

C-Mika with Cherry Cake

链接

题意:

有一个二维平面,一个人a一开始在(0,0)处,平面上有n个商人,你可以操纵a移动,从(x1,y1)移动到(x2,y2)处需要花费|x1-x2|+|y2-y1|秒,如果a移动可以跟商人移动到一点的话,就获得了一个樱桃,然后如果获得了这个樱桃的话,a必须再移动回原点,注意a移动的过程中,商人也会单方向(上、下、左、右)移动,问你a最多能获得多少个樱桃?

思路

可以发现 :
1.假设经过时间t时a可以追上商人,设初始时商人的坐标为(x,y) 经过试试可以知道 比如d=1或者3(向上或者向右走的商人),列个时间的等式:x+y+t=t这种直接约掉了t,所以是追不上的。
所以只有d=2或者4的商人才可能被追上 而且以 d=2向下走为例 x+|y-t|=t 只有当绝对值为正这个方程才有解,所以只要能追上商人,时间t必为 (x+y)/2 。

2.而且d=2或者4的商人是有可能走不到的 :
以d=2为例,商人坐标为(x,y),a(一开始在原点处)需要先走x秒到(x,0) 然后再纵坐标走y,如果商人(x,y) 其y<x,那么当a走到(x,0)时商人y<0了,你就永远也追不到商人了,因为a和商人的速度一样。

3.然后为啥只用找一遍所有的商人而不是一直找直至找不到能走的商人呢?
问了wlx大佬才懂了
答:如果a走到一个商人(x,y)了,然后a回去,商人在这个过程中纵坐标y要减去总时间(x+y),由于x、y均大于0,所以y就小于0了。
类比于上面讲的那个例子,商人一开始纵坐标就小于0了,a走到(x,0)时商人纵坐标也小于0,a和商人纵坐标以相同的速度减小,所以:追到过的商人是不可能再追上的。
综上只需要遍历一次所有商人就好

4.然后本题还需要按x+y升序排序,因为追个商人来回花费的时间t,你需要花费一个综合起来少的时间去追下一个商人,因为这样
才能追到尽可能多的商人,不然不排序的话:比如说第一个商人非常远,为了追上这个牺牲了很多很小的,就不是最优的了

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
double eps=1e-8;
struct w{
	double x;
	double y;
	int d;
	bool operator<(const w& z)const{
	return x+y<z.x+z.y;}
}a[6000];
int cnt,sum;
bool can=false;
int main()
{
   int n;
   cin>>n;
   for(int i=0;i<n;i++) {
   	int x,y,d;
   	cin>>x>>y>>d;
   	if(d==2||d==4){
   		  a[cnt].x=x;
   		  a[cnt].y=y;
   		  a[cnt].d=d;
   		  
   		  cnt++;
	   }
   }
   int ti=0;
   sort(a,a+cnt);
   for(int i=0;i<cnt;i++){
   	   if(a[i].d==2){
   	   	     a[i].y-=ti;
		  }
	   else{
	   	a[i].x-=ti;
	   }
	   if(a[i].d==2){
	   	   if(a[i].y<a[i].x) continue;
	   	   sum++;
	   	   ti+=a[i].x+a[i].y;
	   }
	  else{
	  	 if(a[i].x<a[i].y) continue;
	   	   sum++;
	   	   ti+=a[i].x+a[i].y;
	  }
   }
   cout<<sum;
     
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值