• uva1382 Distant Galaxy


    这道题,我们一开始就能想到O(n^5)的算法---n^4找矩阵的两个对顶角,n用来查找。但因为n<=100,n^5=10^10,所以我们必须用优化算法。我们先枚举上下界(这两条线上面要有点。用了离散化的思想),即局部枚举,然后在用n的时间一列一列的算(上面有点的。用了离散化的思想),最终算法O(n^3)

    #include<iostream>

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct wo{
    int x,y;
    };
    int cmp(wo a,wo b){
    return a.x<b.x;
    }//按行排序 
    wo a[105];
    int n,m;
    int y[105],on[105],on2[105],left1[105];//left是系统内部的一个名字
    int solve(){
    sort(a+1,a+n+1,cmp);
    sort(y+1,y+n+1);
    m=unique(y+1,y+n+1)-(y+1);//去重,计算出去重后直线x=l的个数 
    if(m<=2)return n;
    int ans=0;
    for(int i=1;i<m;i++){
    for(int j=i+1;j<=m;j++){
    int minn=y[i],maxn=y[j];//枚举上边界和下边界 
    int k=0;
    for(int l=1;l<=n;l++){
    if(l==1||a[l].x!=a[l-1].x){
    k++;//新一条直线了 
    on[k]=on2[k]=0;
    left1[k]=left1[k-1]+on2[k-1]-on[k-1];//计算当前这条直线
    //左边(包括自己)有多少个点在上下边界上; 
    }
        if(a[l].y>minn&&a[l].y<maxn)on[k]++;//计算当前直线上在上下边界(不包括)内有多少个点 
        if(a[l].y>=minn&&a[l].y<=maxn)on2[k]++;// 计算当前直线上在上下边界(包括)内有多少个点

    if(k<=2)return n;//上下两条之间即可覆盖所有点则全都能被覆盖

    int count1=0;
    for(int l=1;l<=k;l++){
    ans=max(ans,left1[l]+on2[l]+count1);//第l个直线在边界(矩阵的四条边)上左边有多少个点 
    //计算前k条直线选哪个最好(算出的是那个直线上的点数) 
        count1=max(count1,on[l]-left1[l]);
    }
    }
    }

    return ans;
    }


    int main(){
    int cases=0;
    while(scanf("%d",&n)!=EOF&&n){
    for(int i=1;i<=n;i++){
    scanf("%d%d",&a[i].x,&a[i].y);
    y[i]=a[i].y;
    }
    printf("Case %d: %d ",++cases,solve());

    return 0;
    }
  • 相关阅读:
    golang中channels的本质详解,经典!
    Vim tips——Working with external commands
    go语言中log包的使用
    vue自定义轮播图组件 swiper
    Nerv --- React IE8 兼容方案
    微信小程序实战之 pay(支付页面)
    微信小程序实战之 goods(订餐页)
    微信小程序 自定义组件(stepper)
    微信小程序 自定义组件(modal) 引入组件
    微信小程序之 Swiper(轮播图)
  • 原文地址:https://www.cnblogs.com/c201904xyorz/p/9990791.html
Copyright © 2020-2023  润新知