• SRM DIV2 580 EelAndRabbit


    菜鸟的思考步骤:

    1.设定当前时间为0,鱼往负方向游,这样可以把每个鱼看成在时间轴上的一个线段。t[a]=3,l[a]=4的鱼,看成是线段[3,7]。我们只需要确定找到两个点,使得抓到的鱼最多就行。

    2.首先想到的是找到两个公共线段A,B,使得在A,B处的鱼的鱼最多(当然得除去重复的)。

    3.公共线段上的时间点使等价的,这里可以用线段的顶点来表示该线段(因为线段的顶点一定是某个“鱼线段”的端点,想想还是能明白)。

    4.这样先把所有“鱼线段”的端点收集起来,然后随机选两个不同的点,算出与这两个点处的鱼数,找到其中最大的那个即可。

    5.时间复杂度:O((2n)^2*n)=O(n^3),算法多项式时间内有解。

    菜鸟改过好多次的代码

    import java.util.*;
    import java.util.regex.*;
    import java.text.*;
    import java.math.*;
    
    
    public class EelAndRabbit
    {
        public int getmax(int[] l, int[] t)
        {
            int len = t.length;
            int[] point = new int[2*len];
            int i,j,k,max,tmp;
            //搜集所有端点
            for(i=0;i<len;i++){
                point[2*i]=t[i];
                point[2*i+1]=t[i]+l[i];
            }
            
            //遍历端点,找出捕鱼的最大值
            max=0;
            for(i=0;i<len+len;i++){
                for(j=i+1;j<len+len;j++){
                    if(point[i]==point[j])//注意这两个端点不能一样
                        continue;
                    tmp=0;
                    for(k=0;k<len;k++){
                        if(checkIn(point[i],t[k],t[k]+l[k])||checkIn(point[j],t[k],t[k]+l[k]))
                            tmp++;
                    }
                    if(tmp>max)
                        max=tmp;
                }
            }
            
            return max;
        }
        
        private boolean checkIn(int point,int left,int right){
            return point>=left&&point<=right;
        }
        
    
    }
    //Powered by KawigiEdit 2.1.4 (beta) modified by pivanof!

    大神的代码java

    public class EelAndRabbit 
    { 
      public int getmax(int[] l, int[] t) 
      { 
        int cnt = l.length; 
        int res = 0; 
         
        if(cnt <= 2)  
          return cnt; 
        for(int i=0; i<cnt; i++) 
          for(int j=i+1; j<cnt; j++) 
          { 
            int ta = t[i]; 
            int tb = t[j]; 
            int catchcnt = 0; 
            for(int k=0; k<cnt; k++) 
            { 
              if((t[k]<=ta && t[k]+l[k] >= ta) 
                || (t[k]<=tb && t[k]+l[k] >= tb)) 
                catchcnt++; 
            } 
            if(catchcnt > res) 
              res = catchcnt; 
          } 
        return res; 
      } 
    }

    大神的代码C++:

    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <cassert>
    #include <deque>
    #include <stack>
    #include <set>
    #include <map>
    #include <cstdio>
    #include <cstdlib>
    #include <cctype>
    #include <cmath>
     
    using namespace std;
     
    class EelAndRabbit {
    public:
      int getmax (vector <int> l, vector <int> t); 
        
     
    };
     
    int EelAndRabbit::getmax (vector <int> l, vector <int> t) {
            int res=0;
        int n = l.size();
        for (int i = 0; i < n; ++i) {
          for (int j = 0; j < n; ++j) {
            set<int> s;
            int T = t[i];
            for (int k = 0; k < n; ++k) {
              int head = T-t[k];
              int tail = T-t[k]-l[k];
              if (head >= 0 and tail <= 0) {
                  s.insert(k);
              }
            }
            T = t[j];
            for (int k = 0; k < n; ++k) {
              int head = T-t[k];
              int tail = T-t[k]-l[k];
              if (head >= 0 and tail <= 0) {
                  s.insert(k);
              }
            }
            res = max(res,(int)s.size());
          }
        }
            return res;
        }
     
     
    // Powered by FileEdit
    // Powered by CodeProcessor

    分析:

      算法: Brute Force

      大神代码分析:

        1.大神们都只考虑了鱼头端点,而我还考虑了鱼尾。

          仔细想想,貌似我真的多虑了:公共线段的“尾端”必定为"鱼尾点",“顶端”必定为“鱼头点”。想象一条公共线段CD在AB内移动,D点最多是和B点重合,而C点最多是和A点重合。

        2.虽然C++大神用的set不太高效,但set用起来还是那么方便,学习了。

  • 相关阅读:
    如何在调试PHP代码时不显示错误信息
    如何实现网页组件的随意拖拽
    如何做一个简易的HTML代码编辑器
    如何在网页中动态显示时间
    Luogu2577 | [ZJOI2005]午餐 (贪心+DP)
    Luogu2345 | 奶牛集会 (树状数组)
    解决NahimicSvc32.exe与bilibili直播姬的音频不兼容的问题
    STL函数 lower_bound 和 upper_bound 在算法竞赛中的用法
    电子取证 | 第三届美亚杯(2017)个人赛题解
    快速安装字体.bat批处理脚本
  • 原文地址:https://www.cnblogs.com/wang3/p/3163926.html
Copyright © 2020-2023  润新知