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;
    }


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

  • 相关阅读:
    稳扎稳打Silverlight(13) 2.0交互之鼠标事件和键盘事件
    稳扎稳打Silverlight(17) 2.0数据之详解DataGrid, 绑定数据到ListBox
    再接再厉VS 2008 sp1 + .NET 3.5 sp1(2) Entity Framework(实体框架)之详解 Linq To Entities 之一
    稳扎稳打Silverlight(8) 2.0图形之基类System.Windows.Shapes.Shape
    稳扎稳打Silverlight(11) 2.0动画之ColorAnimation, DoubleAnimation, PointAnimation, 内插关键帧动画
    稳扎稳打Silverlight(21) 2.0通信之WebRequest和WebResponse, 对指定的URI发出请求以及接收响应
    稳扎稳打Silverlight(16) 2.0数据之独立存储(Isolated Storage)
    稳扎稳打Silverlight(9) 2.0画笔之SolidColorBrush, ImageBrush, VideoBrush, LinearGradientBrush, RadialGradientBrush
    稳扎稳打Silverlight(23) 2.0通信之调用WCF的双向通信(Duplex Service)
    游戏人生Silverlight(1) 七彩俄罗斯方块[Silverlight 2.0(c#)]
  • 原文地址:https://www.cnblogs.com/Patt/p/5313455.html
Copyright © 2011-2022 走看看