海贼007

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

菜鸟的思考步骤:

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用起来还是那么方便,学习了。

posted on 2013-07-03 15:28  wzhscript  阅读(235)  评论(0编辑  收藏  举报