LCP 74. 最强祝福力场 (差分,前缀和,二分,离散化)

**力扣测试链接**

思路:

观察数据范围,发现x或y的坐标最大到1e9的大小,不能直接建立差分数组,所以需要进行离散化操作
将所有坐标提取出来,排序后,以下标作为新的坐标位置,再按照离散化操作后进行二维差分操作,从而得到重叠次数最多的答案

题解:

typedef  long long ll;
class Solution {
public:

    void add(int x1,int y1,int x2,int y2,vector<vector<ll>>&diff)
    {
        diff[x1][y1]++;
        diff[x1][y2+1]--;
        diff[x2+1][y1]--;
        diff[x2+1][y2+1]++;

    }

    int search(ll x,vector<ll>&xp)
    {
        int ans=0;
        int l=0;
        int r=xp.size()-1;
        while(l<=r)
        {
            int mid = (l+r)/2;
            if(xp[mid]>=x)
            {
                ans=mid;
                r=mid-1;
            }
            else
            {
                l=mid+1;
            }
        }
        return ans+1;
    }


    int fieldOfGreatestBlessing(vector<vector<int>>& forceField) {
        set<ll>x;
        set<ll>y;
        for(int i=0;i<forceField.size();i++)
        {
            ll xx = forceField[i][0];
            ll yy = forceField[i][1];
            ll r = forceField[i][2];
            x.insert((xx<<1)+r);
            x.insert((xx<<1)-r);
            y.insert((yy<<1)-r);
            y.insert((yy<<1)+r);
        }

        int sizex = x.size();
        int sizey = y.size();
        vector<ll>xp;
        vector<ll>yp;
        for(auto i:x)
        {
            xp.push_back(i);
        }
        for(auto i:y)
        {
            yp.push_back(i);
        }

        sort(xp.begin(),xp.end());
        sort(yp.begin(),yp.end());

        vector<vector<ll>>diff(sizex+2,vector<ll>(sizey+2,0));

        for(int i=0;i<forceField.size();i++)
        {
            ll x = forceField[i][0];
            ll y = forceField[i][1];
            ll r = forceField[i][2];
            ll x1 = (x<<1)-r;
            ll y1 = (y<<1)-r;
            ll x2 = (x<<1)+r;
            ll y2 = (y<<1)+r;
            ll x3 = search(x1,xp);
            ll x4 = search(x2,xp);
            ll y3 = search(y1,yp);
            ll y4 = search(y2,yp);
            add(x3,y3,x4,y4,diff);
        }
        ll ans=0;
        for(int i=1;i<diff.size();i++)
        {
            for(int j=1;j<diff[0].size();j++)
            {   
                diff[i][j]+=diff[i-1][j]+diff[i][j-1]-diff[i-1][j-1];
                ans = max(ans,diff[i][j]);
            }
        }
        return ans;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值