zoukankan      html  css  js  c++  java
  • 东方14模拟赛之岛屿

    02:岛屿

    总时间限制: 
    40000ms
     
    单个测试点时间限制: 
    4000ms
     
    内存限制: 
    128000kB
    描述

    从前有一座岛屿,这座岛屿是一个长方形,被划为N*M的方格区域,每个区域都有一个确定的高度。不幸的是海平面开始上涨,在第i年,海平面的高度为t[i]。如果一个区域的高度小于等于海平面高度,则视为被淹没。那些没有被淹没的连通的区域够成一个连通块。现在问第i年,这样的连通块有多少个。

        例如:第一年海平面高度为1,有2个连通块。

                          第二年海平面高度为2,有3个连通块。

    输入
    第一行包含两个数N,M。
    接下来是一个N*M的矩阵,第i行第j列表示这个格子的高度h[i][j]
    接下来是一个数T,表示有T天,
    最后一行有T个数,第i个数表示第i天的水位高度。(保证是递增的)
    输出
    输出包含一行T个数,第i个数表示第i天的连通块个数。
    样例输入
    4 5
    1 2 3 3 1
    1 3 2 2 1
    2 1 3 4 3
    1 2 2 2 2
    5
    1 2 3 4 5
    
    样例输出
    2 3 1 0 0
    提示
    对于50%的数据: 1 <= n*m <= 1000, 1<= T <=3000
    对于100%的数据:1<= n <= 3000 , 1<= m <= 3000 , 1<=T<=100000 
    1<= h[i][j] <=10^9
    这题比较尴尬,因为数组开小了给我爆re,导致考试结束前20分钟一直卡到88.。。。。最后读了一遍题才发现
    并查集
    读入数据
    把矩阵转化为一条链
    把链按照高度排序 (降序
    我们倒着枚举高度值
    (此处有优化吗,要是当前高度无法达到,那么记录此时i值为tmp,下次从tmp开始枚举岛屿
    记录vis表示,当前岛屿可已经可以永远漏出水面,
    如果枚举到高度高于水面并且没有被记录的,此时计数器++
    并且查看他上下左右是否有被访问的点
    要是有的话查看他的祖先是否与该点祖先相同,不同则cnt--并且合并
    说明此时可以作为连通块一部分
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 3002;
    int map[maxn][maxn],id[maxn][maxn];
    bool vis[maxn*maxn];int father[maxn*maxn];
    #define LL long long
    int c;
    int n,m,q;
    struct node{
        int x,y,high,id;
    }miku[maxn*maxn];
    bool cmp(node a,node b)
    {
        return a.high>b.high;
    }
    LL ccnt=0,ans[maxn*1000];int t[maxn*1000],cnt=0;
    int fs[5]={1,0,-1,0,1};
    inline int find(int x)
    {
        if(father[x]!=x) father[x]=find(father[x]);
        return father[x];
    }
    int pd(int x,int y)
    {
        vis[id[x][y]]=1;
        int tmp=0;
        for(int i=0;i<4;i++)
        {
            int xx=x+fs[i];
            int yy=y+fs[i+1];    
            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&vis[id[xx][yy]])
            {
                int f1=find(id[x][y]),f2=find(id[xx][yy]);
                if(f1!=f2)
                {
                    father[f2]=f1;
                    tmp++;
                }
            }
        }
        return tmp;
    }
    int main()
    {    
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&map[i][j]),miku[++cnt].high=map[i][j],miku[cnt].x=i,father[cnt]=cnt,
            miku[cnt].y=j;
        sort(miku+1,miku+cnt+1,cmp);
        for(int i=1;i<=cnt;i++)
        {
            id[miku[i].x][miku[i].y]=i;
        }
            scanf("%d",&q);
        for(int i=1;i<=q;i++) scanf("%d",&t[i]);
        int tmp=1;
        for(int k=q;k>=1;k--)
        {
            for(int i=tmp;i<=cnt;i++)
            {
                if(miku[i].high>t[k])
                {
                    if(!vis[i])
                    {
                        ccnt++;
                        ccnt-=pd(miku[i].x,miku[i].y);
                    }
                }
                else 
                {
                    tmp=i;
                    break;
                }
            }
            ans[k]=ccnt;
        }
        for(int i=1;i<=q;i++)
            printf("%lld ",ans[i]);
        return 0;
    }
  • 相关阅读:
    绕过卡巴斯基等杀软抓取 lsass 内存踩坑
    Redis 未授权访问 getshll
    linux 中用 sed 指令 删除/添加 指定行首内容
    使用 git 的时候,出现很多别人的commit
    关于近源渗透测试的免杀
    GIT 使用
    web安全入门(更新中)
    一篇入门代码审计
    动态加载dll的实现+远线程注入
    spring系列cve poc编写
  • 原文地址:https://www.cnblogs.com/sssy/p/7208412.html
Copyright © 2011-2022 走看看