zoukankan      html  css  js  c++  java
  • OpenJudge 东方14ACM小组 / 20170123 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
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm> 
     5 using namespace std;
     6 int t[100010],ans[100010],f[9000010],n,m,tot,si; 
     7 struct node{
     8     int x,y,high;
     9 }a[9000010];
    10 bool vis[9000010];
    11 int cmp(node i,node j){return i.high>j.high;}
    12 int dx[]={0,0,1,-1};
    13 int dy[]={-1,1,0,0};
    14 int find(int x){
    15     if(x==f[x]) return x;
    16     else return f[x]=find(f[x]);
    17 }
    18 void solve(){
    19     int sum=0,pos=1;
    20     sort(a+1,a+tot+1,cmp);
    21     for(int p=si;p>=1;p--){
    22         for(int i=pos;i<=tot;i++){
    23             int h=a[i].high,x=a[i].x,y=a[i].y;
    24             if(h<=t[p]){ pos=i;break; }
    25             if(h>t[p]&&!vis[(x-1)*m+y]) {
    26                 sum++;vis[(x-1)*m+y]=true;
    27                 for(int j=0;j<4;j++){
    28                     int nx=x+dx[j],ny=y+dy[j];
    29                     int k1=find((nx-1)*m+ny),
    30                         k2=find((x-1)*m+y);
    31                     if(nx>0&&nx<=n&&ny>0&&ny<=m
    32                       &&vis[k1]&&k1!=k2){
    33                           sum--;f[k1]=k2;
    34                       }
    35                 }
    36             }
    37         }
    38         ans[p]=sum;
    39     }
    40     for(int i=1;i<=si;i++) printf("%d ",ans[i]);
    41 }
    42 int main()
    43 {
    44     scanf("%d%d",&n,&m);
    45     for(int i=1;i<=n;i++)
    46       for(int j=1;j<=m;j++){
    47           scanf("%d",&a[++tot].high);
    48           a[tot].x=i;a[tot].y=j;
    49       }
    50     for(int i=1;i<=tot;i++) f[i]=i;
    51     scanf("%d",&si);
    52     for(int i=1;i<=si;i++) scanf("%d",&t[i]);
    53     solve();
    54     return 0;
    55 }

    神一样的倒序并查集。。。。

  • 相关阅读:
    【原】Ubuntu13.04安装、卸载Gnome3.8
    【原】安装、卸载、查看软件时常用的命令
    【原】中文Ubuntu主目录下的文档文件夹改回英文
    【原】Ubuntu ATI/Intel双显卡 驱动安装
    【转】Hadoop vs Spark性能对比
    【译】Spark调优
    【转】Spark源码分析之-scheduler模块
    【转】Spark源码分析之-deploy模块
    【转】Spark源码分析之-Storage模块
    【转】弹性分布式数据集:一种基于内存的集群计算的容错性抽象方法
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6344791.html
Copyright © 2011-2022 走看看