[2016-03-20][UVALive][3905][Meteor]

  • 时间:2016-03-20 20:14:20 星期日

  • 题目编号:[2016-03-20][UVALive][3905][Meteor]

  • 题目大意:给定一定大小的相框,相框的右下角为坐标原点,给定n个星星的起始位置和运动方向,问相框内最多能捕捉到多少星星

  • 方法:

    • 把星星的运动方向分解成x和y两个方向,计算两个方向经过相框的时间,得到每个星星在相框的时间范围,题目就转换成,最多区间相交问题
    • 计算时间:
      • 计算直线上x为起点,a为增量,经过边界为w的时间对应的l和r
      • 已知 0 < x + at < w —->得到是时间的范围
    • 最多区间相加问题:
      • 区间的左右端点记录成一个时间,按端点大小排序,遇到一个左端点,++cnt,遇到一个右端点–cnt,当遇到的左右端点值相同时,先处理右端点
    • 小小优化:
      • 计算时间的时候,0 < x + at < w 得到临界条件 t = (w-x)/a || t = -x/a 这里a为1~10的数字,只需要乘上lcm(1~10)=2520,就可以不用double类型了
  1. //优化前
  2. #include <algorithm>
  3. #include <cstdio>
  4. using namespace std;
  5. #define FOR(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
  6. const int maxn = 100000 + 10;
  7. struct Event{
  8. double x;
  9. int type;
  10. Event(){};
  11. Event(double mX,int mType):x(mX),type(mType){}
  12. bool operator < (const Event & a)const{
  13. return x < a.x || (x == a.x && type > a.type);
  14. }
  15. }e[maxn * 2];
  16. void update(int x,int a,int w,double &l,double &r){
  17. if(a == 0){
  18. //无解
  19. if(x <= 0 || x >= w) r = l - 1;
  20. }else if(a > 0){
  21. l = max(l,-(double)x/a);
  22. r = min(r,(double)(w - x)/a);
  23. }else {
  24. l = max(l,(double)(w - x)/a);
  25. r = min(r,-(double)x/a);
  26. }
  27. }
  28. int main(){
  29. int t,w,h,n,x,y,a,b,cnt,ans,cur;
  30. double l,r;
  31. scanf("%d",&t);
  32. while(t--){
  33. scanf("%d%d%d",&w,&h,&n);
  34. cnt = 0;
  35. FOR(i,0,n){
  36. scanf("%d%d%d%d",&x,&y,&a,&b);
  37. l = 0,r = 1E9;
  38. update(x,a,w,l,r);
  39. update(y,b,h,l,r);
  40. if(r > l){
  41. e[cnt++] = Event(l,0);
  42. e[cnt++] = Event(r,1);
  43. }
  44. }
  45. sort(e,e + cnt);
  46. cur = 0,ans = 0;
  47. FOR(i,0,cnt){
  48. if(e[i].type) --cur;
  49. else ans = max(++cur,ans);
  50. }
  51. printf("%d\n",ans);
  52. }
  53. return 0;
  54. }
  1. //优化后
  2. #include <algorithm>
  3. #include <cstdio>
  4. using namespace std;
  5. #define FOR(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
  6. const int maxn = 100000 + 10;
  7. struct Event{
  8. int x,type;
  9. Event(){};
  10. Event(int mX,int mType):x(mX),type(mType){}
  11. bool operator < (const Event & a)const{
  12. return x < a.x || (x == a.x && type > a.type);
  13. }
  14. }e[maxn * 2];
  15. void update(int x,int a,int w,int &l,int &r){
  16. if(a == 0){
  17. //无解
  18. if(x <= 0 || x >= w) r = l - 1;
  19. }else if(a > 0){
  20. l = max(l,-x*2520/a);
  21. r = min(r,(w - x)*2520/a);
  22. }else {
  23. l = max(l,(w - x)*2520/a);
  24. r = min(r,-x*2520/a);
  25. }
  26. }
  27. int main(){
  28. int t,w,h,n,x,y,a,b,cnt,ans,cur,l,r;
  29. scanf("%d",&t);
  30. while(t--){
  31. scanf("%d%d%d",&w,&h,&n);
  32. cnt = 0;
  33. FOR(i,0,n){
  34. scanf("%d%d%d%d",&x,&y,&a,&b);
  35. l = 0,r = 1E9;
  36. update(x,a,w,l,r);
  37. update(y,b,h,l,r);
  38. if(r > l){
  39. e[cnt++] = Event(l,0);
  40. e[cnt++] = Event(r,1);
  41. }
  42. }
  43. sort(e,e + cnt);
  44. cur = 0,ans = 0;
  45. FOR(i,0,cnt){
  46. if(e[i].type) --cur;
  47. else ans = max(++cur,ans);
  48. }
  49. printf("%d\n",ans);
  50. }
  51. return 0;
  52. }

来自为知笔记(Wiz)

时间: 2024-08-06 09:52:26

[2016-03-20][UVALive][3905][Meteor]的相关文章

分布式技术一周技术动态 2016.03.20

分布式系统实践 1. 基于Mesos和Docker的分布式计算平台 https://mp.weixin.qq.com/s?__biz=MzAxMDgzOTA2Mw==&mid=402769128&idx=1&sn=cea3ad1357bd9312acf1768c0a493bfd&scene=1&srcid=0318BTuxT0fsFYwPjpeyuDOa&key=710a5d99946419d90fbc1e7600cce055b6e997d6afafc74c

第四周(2016/03/20)

这周主要是做了一些JAVA的学习 静态关键字,静态代码块,单例设计模式,还有静态的应用,主要体现在做了一个处理数组的类 学习了子父类继承的关系,以及一些隐式的代码例如继承父类的构造函数默认第一行有空参数的super();  还有一些调用关系 学习了抽象类和应用,java的单继承,和多继承,还有实现接口,做了一些继承的代码测试什么的 关于模版方法模式,就是关于一些接口,interface 和implements  目前这个还没学完. 其实学的不会说很多,但是我觉得比较细节化,做一些相关的笔记和一些

LA 3905 Meteor

给出一些点的初始位置(x, y)及速度(a, b)和一个矩形框,求能同时出现在矩形框内部的点数的最大值. 把每个点进出矩形的时刻分别看做一个事件,则每个点可能对应两个事件,进入事件和离开事件. 按这些事件的发生时间进行排序,然后逐个扫描,遇到进入事件cnt++,遇到离开事件--cnt,用ans记录cnt的最大值. 对时间相同情况的处理,当一个进入事件的时刻和离开事件的时刻相同时,应该先处理离开事件后处理进入事件. 因为速度(a, b)是-10~10的整数,所以乘以LCM(1,2,3,,,10)

LA - 3905 ——Meteor 流星

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16454 1.对于每一颗流星而言,真正有意义的是它穿越矩形的有效时间,所以其实我们需要得到所有流星的有效时间 2.这样的话,原问题就转化更加具体的:某个时刻最多同时穿过多少个时间段? 解决方案: 将每一个时间区间,转化为两个事件:开始事件和结束事件.我们对所有事件按照时间排序,然后我们有一个初始化为0的tot变量计数,接着遍历这个序列,遇到开始事件就+1,遇到结束时间就

2016/02/20 codes

<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title>2016/02/20</title></head><body><div id="mainDiv"> <div id = "content"> <div id = &qu

3905 - Meteor

The famous Korean internet company nhn has provided an internet-based photo service which allows The famous Korean internet company users to directly take a photo of an astronomical phenomenon in space by controlling a high-performance telescope owne

2016/7/20 1:18:29 PyQT5 炫酷的左侧导航效果

2016/7/20 1:18:29  完整code from PyQt5.QtWidgets import (QApplication, QWidget, QHBoxLayout, QTreeWidget, QTreeWidgetItem, QGroupBox) from PyQt5.QtGui import QIcon, QPixmap from PyQt5.QtCore import QSize class Bar_Navigation(QWidget): def __init__(self

【UVALive】3905 Meteor(扫描线)

题目 传送门:QWQ 分析 扫描线搞一搞. 按左端点排序,左端点相同时按右端点排序. 如果是左端点就$ cnt++ $,否则$ cnt-- $ 统计一下$ Max $就行了 代码 #include <bits/stdc++.h> using namespace std; void update(int x,int a,int w,double& L,double& R){ if(a==0){ if(x<=0||x>=w) R=L-1; } else if(a>

2016/09/20

1. Python序列化之pickle模块 - 用于[python特有的类型]和[python基本数据类型]间进行转换 - pickle模块提供了四个功能:dumps.dump.loads.load - json更加适合跨语言 基本数据类型的序列化  pickle仅适用于python 复杂类型的序列化 # import json # dic = {'k1': 'v1'} # print(dic, type(dic)) # # res = json.dumps(dic) # 将python的基本数