• BZOJ1102: [POI2007]山峰和山谷Grz


    【传送门:BZOJ1102


    简要题意:

      给出一张n*n的图,每个格子有一个高度,一个格子的八个方向为它的相邻格子,高度相同的相邻的格子形成连通块,一个连通块的相邻格子的高度如果都比连通块的高度大,则这个连通块称为山谷,如果都比连通块高度小,则称为山峰

      特殊的,如果整张图的高度都相同,则整张图既为山峰又为山谷

      求整张图的山峰和山谷数量


    题解:

      直接dfs找连通块,顺便判断一个连通块四周的高度情况

      结果爆栈了,RoseD飞我说会递归1000000层,所以爆栈

      懒得改,直接写了个手工栈过了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    using namespace std;
    int dx[9]={0,1,-1,0,0,-1,-1,1,1};
    int dy[9]={0,0,0,1,-1,-1,1,-1,1};
    int a[1100][1100],n;
    bool v[1100][1100];
    bool b1,b2;int tx,ty;
    struct node
    {
        int x,y;
    };
    queue<node> q;
    int cur[1100][1100];
    bool check(int tx,int ty,int x,int y)
    {
        if(tx<1||ty<1||tx>n||ty>n||(a[x][y]==a[tx][ty]&&v[tx][ty]==true)) return false;
        return true;
    }
    void dfs(int x,int y)
    {
        q.push((node){x,y});
        cur[x][y]=1;
        while(q.empty()==0)
        {
            node tno=q.front();
            int x=tno.x,y=tno.y;
            v[x][y]=true;
            while(cur[x][y]<=8&&(check(x+dx[cur[x][y]],y+dy[cur[x][y]],x,y)==false)) cur[x][y]++;
            if(cur[x][y]==9)
            {
                q.pop();
                continue;
            }
            int tx=x+dx[cur[x][y]],ty=y+dy[cur[x][y]];
            if(a[tx][ty]>a[x][y]) b1=true;
            else if(a[tx][ty]<a[x][y]) b2=true;
            else
            {
                if(v[tx][ty]==false)
                {
                    q.push((node){tx,ty});
                    cur[tx][ty]=1;
                }
            }
            cur[x][y]++;
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
        memset(v,false,sizeof(v));
        int d1=0,d2=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(v[i][j]==false)
                {
                    b1=b2=false;
                    dfs(i,j);
                    if(b1==false&&b2==true) d1++;
                    else if(b1==true&&b2==false) d2++;
                }
            }
        }
        if(d1==0&&d2==0){printf("1 1
    ");return 0;}
        else printf("%d %d
    ",d1,d2);
        return 0;
    }

     

  • 相关阅读:
    JAVA实现微信支付功能
    avue设置表格显示图片
    职工管理系统----删除职工
    职工管理系统---显示职工
    职工管理系统---读文件
    职工管理系统---写文件
    职工管理系统-------添加职工
    职工管理系统-----实现职工类
    职工管理系统-------实现退出功能
    职工管理系统-------菜单功能
  • 原文地址:https://www.cnblogs.com/Never-mind/p/9739194.html
Copyright © 2020-2023  润新知