• LOJ P2653 山峰和山谷 Ridges and Valleys 题解


    每日一题 day70 打卡

    Analysis

    这道题的突破口是每个山峰或山谷上的高度是相同的,根据这点我们就可以用广搜来解决。

    这样我们基本的思路就是广搜从每个点开始,搜它能走到的高度相同的格子,且将它标记为走过,这样我们就可以在时间范围内遍历整个图了。

    但是如何判断当前遍历的连通块是否是山峰还是山谷呢?(要知道并不是每一个连通块都是山峰或山谷)

    我们可以通过当前遍历的且是非当前连通块的点与连通块高度比较,连通块高度高则有可能是山峰,反之亦然。

    只有这个也不能确定,我们需要在广搜后再加一个判断,如果搜完的连通块既有可能是山峰,也有可能是山谷,那它既不是山峰,也不是山谷。

    以下是代码实现:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 #define int long long
     7 #define maxn 1010
     8 #define rep(i,s,e) for(register int i=s;i<=e;++i)
     9 #define dwn(i,s,e) for(register int i=s;i>=e;--i)
    10 using namespace std;
    11 inline int read()
    12 {
    13     int x=0,f=1;
    14     char c=getchar();
    15     while(c<'0'||c>'9') {if(c=='-') x=-x; c=getchar();}
    16     while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    17     return f*x;
    18 }
    19 inline void write(int x)
    20 {
    21     if(x<0){putchar('-');x=-x;}
    22     if(x>9)write(x/10);
    23     putchar(x%10+'0');
    24 }
    25 int n,ans1,ans2;
    26 int map[maxn][maxn];
    27 int book[maxn][maxn];
    28 int dx[10]={0,0,0,1,-1,1,1,-1,-1},dy[10]={0,1,-1,0,0,1,-1,1,-1};
    29 struct node
    30 {
    31     int x,y;
    32 }point[maxn];
    33 queue<node> q;
    34 void bfs(int sx,int sy) 
    35 {
    36     int flag1=0,flag2=0;
    37     q.push((node){sx,sy});
    38     while(!q.empty())
    39     {
    40         node now=q.front();
    41         q.pop();
    42         rep(i,1,8)
    43         {
    44             node af;
    45             af.x=now.x+dx[i];
    46             af.y=now.y+dy[i];
    47             if(af.x<1||af.y<1||af.x>n||af.y>n) continue;
    48             if(book[af.x][af.y]==0&&map[sx][sy]==map[af.x][af.y])
    49             {
    50                 book[af.x][af.y]=1;
    51                 q.push(af);
    52             }
    53             else if(map[sx][sy]>map[af.x][af.y]) flag1=1;
    54             else if(map[sx][sy]<map[af.x][af.y]) flag2=1;
    55         }
    56     }
    57     if(flag1==1&&flag2==0) ++ans1;
    58     if(flag2==1&&flag1==0) ++ans2;
    59 }
    60 signed main()
    61 {
    62     n=read();
    63     rep(i,1,n)
    64         rep(j,1,n)
    65             map[i][j]=read();
    66     int s=map[1][1],cnt=0;
    67     rep(i,1,n)
    68         rep(j,1,n)
    69             if(map[i][j]==s) ++cnt;
    70     if(cnt==n*n)
    71     {
    72         write(1);
    73         putchar(' ');
    74         write(1);
    75         return 0;
    76     }
    77     rep(i,1,n)
    78         rep(j,1,n)
    79             if(book[i][j]==0)
    80                 bfs(i,j);
    81     write(ans1);
    82     putchar(' ');
    83     write(ans2);
    84     return 0;
    85 }

    如有失误请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    【Swing】简单的计算器
    【SQL】嵌套查询与子查询
    【网络协议抓包分析】TCP传输控制协议(连接建立、释放)
    【网络协议抓包分析】IP互联网协议
    ******常见数据库笔试题*****
    OSI参考模型 VS TCP/IP参考模
    TCP/IP四层模型
    数组实现栈的功能
    子网掩码怎么计算
    C# 启动和结束一个线程
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/12381639.html
Copyright © 2020-2023  润新知