栅栏-Codechef 2019年4月漫长的挑战

时间:2019-05-21 11:28:33

标签: c++ algorithm data-structures c++14

在以下问题中,对于下面给出的代码,我仅获得2个正确答案。请帮助我解决什么情况。

https://www.codechef.com/problems/FENCE

这个想法是考虑行进和列进时遇到的每一个栅栏。

一旦遇到植物,则计算2个边(沿行和列遍历),然后检查前一条在行或列中的邻接关系。如果相邻,则减去2个公共边。

#include <bits/stdc++.h>
using namespace std;

typedef long long int ll;

bool sortbysec(const pair<ll,ll> &a,const pair<ll,ll> &b) 
    { 
    return (a.second < b.second); 
    } 

int main() {

    ll t;
    cin>>t;
    while(t--){
        ll n,m,k;
        cin>>n>>m>>k;
        vector<pair<ll,ll>> a(k,make_pair(0,0));
        ll count=4;
        if(k==0) count=0;
        else{
            ll x,y;
            int l=1;
            cin>>x>>y;
            a[0]=make_pair(x,y);

            for(ll i=1;i<k;i++){
            ll x,y;
            cin>>x>>y;
            a[l]=make_pair(x,y);
            if(a[l]!=a[l-1]) l++;
            }

            sort(a.begin(),a.end());

            for(ll i=1;i<k;i++){

            if((a[i-1].first==a[i].first && a[i-1].second+1==a[i].second)) count-=2;
            count+=2;
            }

            sort(a.begin(),a.end(),sortbysec);

            for(ll i=1;i<k;i++){

            if((a[i-1].second==a[i].second && a[i-1].first+1==a[i].first)) count-=2;
            count+=2;
            }
        }
        cout<<count<<endl;
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

您不能编写用于构建网格的算法,因为它至少具有O(MN)的复杂度,并且在约束NM <= 10 ^ 18中可以看到,这是不可行的。

您必须编写一个复杂度为O(K)的算法,因为我们知道植物的数量K <= 10 ^ 5。

这很容易做到:

  1. 创建一个HashMap<Integer, HashSet<Integer>>,在其中放置所有工厂值。目的是查询O(1)中的相邻单元格。

  2. 然后为每个植物添加4 - adjacent plants到篱笆总和中。例如。如果要测试{3, 7000}左侧是否有植物,请执行map.containsKey(2) && map.get(2).contains(7000)。这样,您甚至不需要在网格边界处对植物进行特殊处理。