zoukankan      html  css  js  c++  java
  • UVA 1398 Meteor

    传送门

    Solution:

    记一颗流星在视野内的时间段为(L, R),

    为了使所有(L, R)都取整数,首先将坐标放大。

    放大倍数可取为

        LCM(1, 2, ..., 10)= 2520

    接着计算:从0时刻开始,每单位时间内入画的流星数,即数组:

      a[0], ..., a[M]

    显然这可借助线段树,但难免繁琐。

    考虑到这道题区间操作的特殊性:每次对区间[L, R)内的元素加一,用差分序列更方便。

    数组a[0...M]的差分序列d[0...M]定义为:

      d[0]=a[0],

      d[i]=a[i]-a[i-1], i>0

    对于这道题,我们只要维护数组a[ ]的差分序列d[ ]即可。

    ------------------------------------------------------------------------------------

    Implementation:

    当然可以先离散化,但下面的实现用map (also called "asscociated array") 避免离散化:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=1e5+5;
    const int INF=0x3f3f3f3f;
    
    int x[N], y[N], a[N], b[N], t[N][2];
    int n, w, h;
    
    map<int,int> mp;
    
    //! Repeating
    void get_t(int i){ int tx1, tx2, ty1, ty2; if(a[i]==0){ if(x[i]>0 && x[i]<w){ tx1=0; tx2=INF; } else{ tx1=tx2=0; } } else{ tx1=-x[i]/a[i]; tx2=(w-x[i])/a[i]; } if(b[i]==0){ if(y[i]>0 && y[i]<h){ ty1=0; ty2=INF; } else{ ty1=ty2=0; } } else{ ty1=-y[i]/b[i]; ty2=(h-y[i])/b[i]; } t[i][0]=max(min(tx1, tx2), min(ty1, ty2)); t[i][1]=min(max(tx1, tx2), max(ty1, ty2)); t[i][0]=max(t[i][0], 0); if(t[i][1]>t[i][0]){ mp[t[i][0]+1]++; mp[t[i][1]]--; } } int main(){ int T; for(cin>>T; T--; mp.clear()){ cin>>w>>h>>n; w*=2520; h*=2520; mp[0]; for(int i=0; i<n; i++){ cin>>x[i]>>y[i]>>a[i]>>b[i]; x[i]*=2520, y[i]*=2520; get_t(i); } // As with any other type specifier, we can define mutiple variables using auto. // Because a declaratin can involve only a single base type, the initializers for all the // variables in the declaration must have types that are consistent with each other. int ans =0;
         // tedious auto i
    =mp.begin(), j=i; ++j; for(; j!=mp.end(); ++i, ++j){ j->second+=i->second; ans=max(ans, j->second); } cout << ans <<' '; } return 0; }


    代码写得很差劲:

    •   重复,不符合 Keep DRY (Don't Repeat Yourself)原则
    •        所有的数组其实都不需要开
    •        计算前项和(prefix sum)过于繁琐,显得很笨 (dull)

    ---------------------------------------------------------------------------------------

    总之丑得看不下去了,代码写成这样,和咸鱼有什么区别。。。。。

    Enhanced:

    #include <bits/stdc++.h>
    using namespace std;
    
    
    const int N=1e5+5;
    const int INF=0x3f3f3f3f;
    int x, y, a, b;
    int n, w, h;
    
    map<int,int> mp;
    
    
    void get_t(int &L, int &R, int v, int p, int b){
        if(v){
            L=max(L, min(-p/v, (b-p)/v));
            R=min(R, max(-p/v, (b-p)/v));
        }
        else if(p<=0 || p>=b) R=L;
    }
    
    int main(){
        ios::sync_with_stdio(false);
    
        int T;
        for(cin>>T; T--; mp.clear()){
            cin>>w>>h>>n;
            w*=2520;
            h*=2520;
    
    
            for(int i=0, L, R; i<n; i++){
                cin>>x>>y>>a>>b;
                x*=2520, y*=2520;
                L=0, R=INF;
                get_t(L, R, a, x, w);
                get_t(L, R, b, y, h);
    
                if(R>L)
                    mp[L]++, mp[R]--;
            }
            int ans =0, sum=0;
            
            for(auto i:mp){
                sum+=i.second;
                ans=max(sum, ans);
            }
            cout << ans <<'
    ';
        }
        return 0;
    }

     -----------------------------------------------

    还有一种更为美妙的实现:

    #include <bits/stdc++.h>
    using namespace std;
    
    
    const int N=1e5+5;
    const int INF=0x3f3f3f3f;
    int x, y, a, b;
    int n, w, h;
    
    vector<pair<int,int>> vec;
    
    //Don't repeat yourself.  (keep DRY)
    
    void get_t(int &L, int &R, int v, int p, int b){
        if(v){
            L=max(L, min(-p/v, (b-p)/v));
            R=min(R, max(-p/v, (b-p)/v));
        }
        else if(p<=0 || p>=b) R=L;
    }
    
    int main(){
        ios::sync_with_stdio(false);
    
        int T;
        for(cin>>T; T--; ){
            cin>>w>>h>>n;
            w*=2520;
            h*=2520;
    
            vec.clear();
    
            for(int i=0, L, R; i<n; i++){
                cin>>x>>y>>a>>b;
                x*=2520, y*=2520;
                L=0, R=INF;
                get_t(L, R, a, x, w);
                get_t(L, R, b, y, h);
                if(R>L){    //error-prone
                    vec.push_back({L, 1});
                    vec.push_back({R, -1});
                }
            }
            sort(vec.begin(), vec.end());
            int ans =0, sum=0;
            
            for(auto i:vec){
                sum+=i.second;
                ans=max(sum, ans);
            }
            cout << ans <<'
    ';
        }
    
        return 0;
    }


    言不尽意,读者自己欣赏吧。。。。。。。。。

  • 相关阅读:
    2015网易校招Java开发工程师(技术架构)在线笔试题
    2015百度校招用户行为分析研发工程师笔试题
    2016届百度实习生前端笔试题上海卷a
    数据库 三范式最简单最易记的解释
    从几个sample来学习JAVA堆、方法区、JAVA栈和本地方法栈
    C++中虚函数和纯虚函数的总结
    MFC一些基本控件操作的总结
    单文档多视图一些基本操作
    MFC单文档静态分割视图
    iOS通讯录相关知识-浅析
  • 原文地址:https://www.cnblogs.com/Patt/p/5313455.html
Copyright © 2011-2022 走看看