廣場舞 藍橋真題

https://www.dotcpp.com/oj/problem1838.html

50%數據參考博客https://blog.csdn.net/qq_39562286/article/details/80033097

很多博客的思路都是 枚舉每個小正方形的右上角 然後判斷其餘三個角是不是在多邊形內 但是當出現斜率不存在的直線時就不好使了 比如下面這個樣例

6
0 0
2 0
2 3
1 3
1 1
0 3

本應輸出4 按上述方法卻得6 所以除非保證所有直線斜率全都存在 否則不可行

 

正解就很巧妙得避開這個問題 對每一列正方形(假設只有連續的一段)一定有兩條直線封住上下底 n^2的暴力枚舉即可

還有就是ceil與floor的使用 mark

 

 

#include <bits/stdc++.h>
using namespace std;
const double N=1000000000000000000.0;
const int maxn=1e3+10;

struct node1
{
    int x,y;
};

struct node2
{
    node1 p1,p2;
};

struct node3
{
    double yl,yr;
};

node1 point[maxn];
node2 line[maxn];
node3 pre[maxn];
int n;

double gety(double x,node2 l)
{
    double y,x1,y1,x2,y2;
    x1=l.p1.x,y1=l.p1.y,x2=l.p2.x,y2=l.p2.y;
    y=(y2-y1)*(x-x1)/(x2-x1)+y1;
    return y;
}

bool cmp(node3 n1,node3 n2)
{
    return n1.yl<n2.yl;
}

int solve()
{
    int res,cnt,minn,maxx,l,r,i,j;
    minn=1000,maxx=-1000;
    for(i=0;i<n;i++){
        minn=min(minn,point[i].x),maxx=max(maxx,point[i].x);
    }
    res=0;
    for(i=minn+1;i<=maxx;i++){
        cnt=0;
        for(j=0;j<n;j++){
            l=line[j].p1.x,r=line[j].p2.x;
            if(l<=i-1&&i<=r){
                pre[cnt].yl=gety(i-1,line[j]),pre[cnt].yr=gety(i,line[j]);
                cnt++;
            }
        }
        sort(pre,pre+cnt,cmp);
        for(j=0;j<cnt/2;j++){
            l=int(ceil(max(pre[2*j].yl,pre[2*j].yr)));
            r=int(floor(min(pre[2*j+1].yl,pre[2*j+1].yr)));
            if(l<r) res+=(r-l);
        }
    }
    return res;
}

int main()
{
    int i,ans;
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d%d",&point[i].x,&point[i].y);
    }
    for(i=0;i<n;i++){
        line[i].p1=point[i],line[i].p2=point[(i+1)%n];
        if(line[i].p1.x>line[i].p2.x){
            swap(line[i].p1,line[i].p2);
        }
    }
    printf("%d\n",solve());
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章