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 <<'\n'; } 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 <<'\n';
    }
    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 <<'\n';
    }

    return 0;
}


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

posted @ 2016-03-23 22:40  Pat  阅读(179)  评论(0编辑  收藏  举报