• 搜索 引水入城 1514


    题目链接

    题目来自洛谷1514 引水入城

    很清新的一道搜索题,先造出每个蓄水厂的可浇灌区间,因为如果区间不连贯,必定会出现交叉相灌的情况,交叉意味着两条路都能走,假设不成立。

    再贪心求得最小覆盖值,值得一说的是贪心用的方法是跳过大区间内包含的小区间,直到下一个与上一个r值不相交l值出现时答案才加一。

    其他没什么好说的了。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int ans=99999999,maxn=99999999;
    int m,n,cnt,fl,now;
    int be[502],a[502][502],v[502][502];
    struct llo{
        int l,r;
    } e[503],d[503];
    int cmp(llo x,llo y){
        if(x.l==y.l)    return x.r>y.r;    
        return x.l<y.l;
    }
    void fugai(int num,int nx,int ny){
        v[nx][ny]=1;
        if(nx==n){
            be[ny]=1;
            e[num].l=min(e[num].l,ny);
            e[num].r=max(e[num].r,ny);
        }
        if(nx!=1&&a[nx][ny]>a[nx-1][ny]&&v[nx-1][ny]==0){
            fugai(num,nx-1,ny);
        }
        if(nx!=n&&a[nx][ny]>a[nx+1][ny]&&v[nx+1][ny]==0){
            fugai(num,nx+1,ny);
        }
        if(ny!=1&&a[nx][ny]>a[nx][ny-1]&&v[nx][ny-1]==0){
            fugai(num,nx,ny-1);
        }
        if(ny!=m&&a[nx][ny]>a[nx][ny+1]&&v[nx][ny+1]==0){
            fugai(num,nx,ny+1);
        }
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }    
        }
        for(int i=1;i<=m;i++)    e[i].l=99999999;
        for(int i=1;i<=m;i++){
            memset(v,0,sizeof(v));
            if(a[1][i]>=a[1][i-1]&&a[1][i]>=a[1][i+1]){
                fugai(i,1,i);
            }
        }
        for(int i=1;i<=m;i++){
            if(be[i]==0)    fl++; 
        }
        if(fl!=0){
            printf("0
    %d",fl);
            return 0;
        }
        now=1;cnt=0;
        for(int i=1;i<=m;i++){
            if(e[i].l==99999999)    continue;
            cnt++;
            d[cnt].l=e[i].l;
            d[cnt].r=e[i].r;
        }
        now=1;int ccc=1;ans=0;
        sort(d+1,d+cnt+1,cmp);
        while(ccc<=m){
            int numm=0;
            while(d[now].l<=ccc){
                printf("%d %d %d
    ",d[now].l,ccc,d[now].r);
                numm=max(numm,d[now].r);
                now++;
            }
            ccc=numm+1;
            ans++;
        }
        printf("1
    %d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    deb包的2种安装安装方法
    苹果全系产品信息查询
    水货的运作流程
    关于手机字库损坏的真相
    关闭IOS更新功能(ios4/5/6)
    c++ builder xe2 字符串转日期
    《windows核心编程》 18章 堆
    《windows核心编程》 17章 内存映射文件
    使用内存映射文件来共享数据
    <转>C++位运算详解
  • 原文地址:https://www.cnblogs.com/jindui/p/11694658.html
Copyright © 2020-2023  润新知