• HDU 3375 XieGang and FanXieGang


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=3375

    题意:给你一个由/和构成的图,求图中不是用作分割图形的/和的数量

    这个题最坑的是n,m是反的!!!

    一种简单直接的方法是将/或放大成3*3,然后直接染色,判断

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    char c[505];
    int a[1505][1505];
    int fx[4]={0,0,-1,1};
    int fy[4]={1,-1,0,0};
    int stx[1505*1505],sty[1505*1505];
    int color;
    int n,m;
    void dfs(int x,int y)
    {
        int top=0;
        stx[top]=x;
        sty[top++]=y;
        a[x][y]=color;
        while(top!=0)
        {
            x=stx[--top];
            y=sty[top];
            for(int i=0;i<4;i++)
            {
                int tx=fx[i]+x,ty=fy[i]+y;
                if (tx<0||tx>=n||ty<0||ty>=m) continue;
                if (a[tx][ty]==0)
                {
                    a[tx][ty]=color;
                    stx[top]=tx;
                    sty[top++]=ty;
                }
            }
        }
    }
    bool check(int x,int y)
    {
        int t=-1;
        for(int i=0;i<4;i++)
        {
            int tx=fx[i]+x,ty=fy[i]+y;
            if (tx<0||tx>=n||ty<0||ty>=m) continue;
            if (t==-1)
            {
                if (a[tx][ty]!=-1)
                    t=a[tx][ty];
            }
            else
            {
                if (a[tx][ty]==-1) continue;
                if (t!=a[tx][ty]) return false;
            }
        }
        return true;
    }
    int main()
    {
        while(scanf("%d%d",&m,&n)!=EOF)
        {
            n*=3;m*=3;
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    a[i][j]=0;
            n/=3;m/=3;
            for(int i=0;i<n;i++)
            {
                scanf("%s",c);
                for(int j=0;j<m;j++)
                {
                    if (c[j]=='\')
                    {
                        a[i*3][j*3]=-1;
                        a[i*3+1][j*3+1]=-1;
                        a[i*3+2][j*3+2]=-1;
                    }
                    else if (c[j]=='/')
                    {
                        a[i*3][j*3+2]=-1;
                        a[i*3+1][j*3+1]=-1;
                        a[i*3+2][j*3]=-1;
                    }
                }
            } 
            n*=3;m*=3;
            color=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    if (a[i][j]==0)
                    {
                        color++;
                        dfs(i,j);
                    }
            int ans=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    if (a[i][j]==-1)
                        if (check(i,j)) ans++;
            printf("%d
    ",ans/3);
        }
        return 0;
    }

    但是还有更好的方法,将一个/或分成2半

    看看和当前这一半相邻的是否可以染色

    染完色以后只需要看每格的两半是否是同色就行了

    特别注意只有1格的情况,分成两半无法bfs,也就无法染色

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    const int N=505;
    struct pp
    {
        char ch;
        int l[2];
    };
    pp a[N][N];
    struct p
    {
        int x,y,op;
        p(int xx,int yy,int opp)
        {
            x=xx;
            y=yy;
            op=opp;
        }
    };
    int n,m,color;
    char s[N];
    queue<p> que;
    bool pd(int x,int y)
    {
        return (x>=0&&x<n&&y>=0&&y<m);
    }
    void add(int x,int y,int op)
    {
        if (pd(x,y)&&a[x][y].l[op]==-1)
        {
            a[x][y].l[op]=color;
            que.push(p(x,y,op));
        }
    }
    void bfs(int xx,int yy,int opp)
    {
        que.push(p(xx,yy,opp));
        while(!que.empty())
        {
            p t=que.front();
            que.pop();
            int x=t.x,y=t.y,op=t.op;
            if (a[x][y].ch=='/')
            {
                if (op==0)
                {
                    add(x-1,y,!op);
                    if (a[x][y-1].ch=='\')
                        add(x,y-1,op);
                    else add(x,y-1,!op);
                }
                else
                {
                    add(x+1,y,!op);
                    if (a[x][y+1].ch=='\')
                        add(x,y+1,op);
                    else add(x,y+1,!op);
                }
            }
            else
            {
                if (op==0)
                {
                    add(x-1,y,!op);
                    if (a[x][y+1].ch=='/')
                        add(x,y+1,op);
                    else add(x,y+1,!op);
                }
                else
                {
                    add(x+1,y,!op);
                    if (a[x][y-1].ch=='/')
                        add(x,y-1,op);
                    else add(x,y-1,!op);
                }
            }
        }
    }
    int main()
    {
        while(scanf("%d%d",&m,&n)!=EOF)
        {
            for(int i=0;i<n;i++)
            {
                scanf("%s",s);
                for(int j=0;j<m;j++)
                {
                    a[i][j].ch=s[j];
                    a[i][j].l[0]=a[i][j].l[1]=-1;
                }
            }
            if (n==1&&m==1) {printf("0
    ");continue;}
            color=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    for(int k=0;k<2;k++)
                        if (a[i][j].l[k]==-1)
                        {
                            ++color;
                            bfs(i,j,k);
                        }
            int ans=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<m;j++)
                    if (a[i][j].l[0]==a[i][j].l[1])
                        ans++;
            printf("%d
    ",ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    移植ssh到mini2440
    VMware中Ubuntu安装VMware Tools步骤及问题解决方法
    Linux的网卡由eth0变成了eth1,如何修复
    mini2440移植所有驱动到3.4.2内核详细解说
    单片机的一生(感觉在说大部分人)
    mini2440移植linux-3.4.2内核详细解说
    Ubuntu中恢复桌面的上下默认面板命令
    mini2440移植最新u-boot-2012.04.01详细解说
    MyEclipse CI 2018.8.0 官方最新免费版(破解文件+激活工具+破解教程)
    cocos 获取一个骨骼动画多次显示播放
  • 原文地址:https://www.cnblogs.com/bk-201/p/9321793.html
Copyright © 2020-2023  润新知