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

Posted 红洋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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. }




以上是关于[2016-03-20][UVALive][3905][Meteor]的主要内容,如果未能解决你的问题,请参考以下文章

第四周(2016/03/20)

Hive Join - 基于多个条件

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

技嘉z390pro用啥显卡

技嘉Z390主板超频指南,适合入门用户收藏参考

微星z390内存有插槽不识别