现在是凌晨1:55,我终于最后一次提交成功了。
这题以前也写过,大概是在cf上碰到的,我记得当时我也是尝试去找规律(因为想不到其他解法)但是无论如何想到这四个顶点的总面积必须等于小方块的面积没思路了。实际上当你去讨论它的点和边的奇偶性的时候,才算是找到了这道题真正的奥秘。因为在完美矩形里的点和边都需要是偶数的。
先讨论点,除去最外围四个顶点,其余在矩形内的点,都是偶数个端点重叠的(2,4),这样配合上面积计算,我们就可以利用这两个条件判断这堆矩形是不是完美端点了。
另外是扫描线,这算法也是早就看过了,大概这类矩阵面积的题除了数学我也就知道一个扫描线了,第一遍大概没太看明白,思路其实比较简单,就是只考虑竖直方向的线,根据除去边缘两条线以外矩阵内部的每一条线进行拼接后都有重叠的左右两条。这样我们先将所有线统计,然后根据x坐标进行排序,然后将所有x坐标相同的线进行拼接。然后对这个x坐标的两条边进行判断上端点和下端点时候都一致。两边的线做一个特殊判断,是否只存在一条边即可。
但是,为什么现在是凌晨2:03分呢,因为三叶写的题解是JAVA实现的,我寻思着我就写一份C++的提交吧,但是C++的指针算是第一次真正的把我坑到了。其中各种指针转换,让我感觉像在刀尖上跳舞。找了半天发现是某个数组没有赋给指针而是直接在新创建的数组里进行修改了,除了这个还有就是C++的sort判断接口居然和JAVA的sort接口是相反的,在C++里,(p1,p1)→bool:{return p1<p2;}这是正序,但是在JAVA里(p1,p1)→int:{return p1<p2;}是逆序...真有你的,淦!
明天再写一道扫描线熟练一下。
哦对了...这题还有大佬用高等数学解的...我改天再去偷一下。
class Solution {
public:
bool isRectangleCover(vector<vector<int>>& rectangles) {
int len = rectangles.size();
vector<vector<int>> line;
for(int i = 0 ; i < len ; i ++){
// vector<int>* temp = new vector<int>({rectangles[0][0],rectangles[0][1],rectangles[0][3],1});
line.push_back({rectangles[i][0],rectangles[i][1],rectangles[i][3],1});
line.push_back({rectangles[i][2],rectangles[i][1],rectangles[i][3],-1});
}
sort(line.begin(),line.end(),[](const auto &a,const auto &b)->bool{
if(a[0] != b[0])
return a[0]<b[0];
return a[1]<b[1];
});
len *= 2;
vector<pair<int,int>>*l1 = new vector<pair<int,int>>;
vector<pair<int,int>>*r1 = new vector<pair<int,int>>;
for(int l = 0 ; l < len ;){
int r = l;
l1->clear();r1->clear();
while(r<len && line[l][0]==line[r][0])r++;
for(int i=l ;i < r ; i ++){
pair<int,int>cur = make_pair(line[i][1],line[i][2]);
vector<pair<int,int>> *list = line[i][3] == 1?l1:r1;
if(list->empty()){
list->emplace_back(cur);
}else{
pair<int,int> prev = list->at(list->size()-1);
// cout<<prev.first<<" "<<cur.first<<endl;
// cout<<prev.second<<" "<<cur.second<<endl;
if(prev.second>cur.first){
return false;
}else if(prev.second == cur.first){
// cout<<"top:"<<prev.second<<" "<<cur.second<<endl;
// prev.second = cur.second;
list->at(list->size()-1).second = cur.second;
}else{
list->emplace_back(cur);
}
}
}
// cout<<"cmp:"<<l1->size()<<" "<<r1->size()<<endl;
if(l > 0 && r < len){
// cout<<(l1->at(0).second)<<" "<<(r1->at(0).second)<<endl;
if(l1->size()!=r1->size())return false;
for(unsigned long long i = 0 ; i < l1->size() ; i ++){
if(l1->at(i).first == r1->at(i).first&&l1->at(i).second==r1->at(i).second)continue;
// cout<<"!!!";
return false;
}
}else{
if(l1->size()+r1->size()!=1){
return false;
}
}
l = r;
}
return true;
}
};