今日题解------uvalive 2689

今天学到了代码以外的东西,就是你在vj上挂了content ,然后你想更新它,你就要刷新一下,不然你提交的那题可能提交到别的地方。

好了回到重点,本题的题意是:

#include<bits/stdc++.h>
#define de(x) cout<<#x<<"="<<x<<endl;
#define dd(x) cout<<#x<<"="<<x<<" ";
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define repd(i,a,b) for(int i=a;i>=(b);--i)
#define repp(i,a,b,t) for(int i=a;i<(b);i+=t)
#define ll long long
#define mt(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define pdd pair<double,double>
#define pdi pair<double,int>
#define mp(u,v) make_pair(u,v)
#define sz(a) a.size()
#define ull unsigned long long
#define ll long long
#define pb push_back
#define PI acos(-1.0)
#define qc std::ios::sync_with_stdio(false)
const int mod = 1e9+7;
const int maxn = 1e6+9;
const double EPS = 1e-6;
using namespace std;
struct Point{
    int x,y;
}p[maxn];
bool cmp1(Point a,Point b){
    return a.x<b.x;
}
bool cmp2(Point a,Point b){
    return a.y<b.y;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int ansl=0,ansr=0,ans = 1;
        int n;
        int w,h;
        scanf("%d%d%d",&n,&w,&h);
        bool fi = true,fj = true;
        rep(i,0,n){
            scanf("%d%d",&p[i].x,&p[i].y);
            if(p[i].x==0&&p[i].y==0) fi = false;
            if(p[i].x==w&&p[i].y==h) fj = false;
        }
        if(fi) p[n++] = (Point){0,0};
        if(fj) p[n++] = (Point){w,h};
        sort(p,p+n,cmp1);
        rep(i,0,n){
            int lx=p[i].x;
            int l = 0,r = h;
            rep(j,i+1,n){
                if(p[i].x==p[j].x) continue;
                if(min(p[j].x-lx,r-l)>ans){
                    ans = min(p[j].x-lx,r-l);
                    ansl = lx;
                    ansr = l;
                }
                if(p[i].y==p[j].y) break;
                if(p[i].y<p[j].y) r = min(r,p[j].y);
                else l = max(l,p[j].y);
            }
        }
        repd(i,n-1,0){
            int lx=p[i].x;
            int l = 0,r = h;
            repd(j,i-1,0){
                if(p[i].x==p[j].x) continue;
                if(min(lx-p[j].x,r-l)>ans){
                    ans = min(lx-p[j].x,r-l);
                    ansl = p[j].x;
                    ansr = l;
                }
                if(p[i].y==p[j].y) break;
                if(p[i].y<p[j].y) r = min(r,p[j].y);
                else l = max(l,p[j].y);
            }
        }
        sort(p,p+n,cmp2);
        rep(i,1,n){
            if(p[i].y!=p[i-1].y){
                if(min(w,p[i].y-p[i-1].y)>ans){
                    ans = min(w,p[i].y-p[i-1].y);
                    ansl = 0;
                    ansr = p[i-1].y;
                }    
            }
        }
        printf("%d %d %d
",ansl,ansr,ans);
        if(T) cout<<endl;
    }
    return 0;
}

求一个最大正方形,边界可以包含障碍点,内部不能。

解法:

可以看看这个论文:http://www.doc88.com/p-9042008501060.html

我们可以用单调栈来做,但是复杂度是O(nm),不能,但是我们可以用另一个方法,就是那个网站里的算法一,复杂度为O(s*s),s为障点数;

做法就是先加入0,0和w,h这两个点(可以阻止第一类遗漏),先按x坐标排序,枚举每一个左边界,然后在反过来,枚举每一个右边界

然后接着就是矩形左边界和最左重合,右边界和最右重合的情况我门还是遗漏了,所以我们可以按y拍个序,枚举每两个y之间的矩形

代码:

原文地址:https://www.cnblogs.com/chinacwj/p/7979693.html