hdu Farm Irrigation

这题第一感觉是用搜索做,暴力就可以解决,这里将水管转换成一个个3*3的矩阵,然后搜素就可以了。写完之后确实一遍过掉了,31ms。附上代码:

#include"iostream"
#include"stdio.h"
#include"algorithm"
#include"cmath"
#include"queue"
#include"stack"
#include"vector"
#include"string"
#include"string.h"
using namespace std;
const int mx=1005;
int A[3][3]={{0,1,0},{1,1,0},{0,0,0}};
int B[3][3]={{0,1,0},{0,1,1},{0,0,0}};
int C[3][3]={{0,0,0},{1,1,0},{0,1,0}};
int D[3][3]={{0,0,0},{0,1,1},{0,1,0}};
int E[3][3]={{0,1,0},{0,1,0},{0,1,0}};
int F[3][3]={{0,0,0},{1,1,1},{0,0,0}};
int G[3][3]={{0,1,0},{1,1,1},{0,0,0}};
int H[3][3]={{0,1,0},{1,1,0},{0,1,0}};
int I[3][3]={{0,0,0},{1,1,1},{0,1,0}};
int J[3][3]={{0,1,0},{0,1,1},{0,1,0}};
int K[3][3]={{0,1,0},{1,1,1},{0,1,0}};
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int maze[mx][mx];
bool visited[mx][mx];
int m,n,wellspring;
bool judge(int x,int y)
{
    if(x>=0&&x<3*m&&y>=0&&y<3*n&&maze[x][y]==1&&!visited[x][y])
        return true;
    return false;
}
void dfs(int x,int y)
{
    int dx,dy;
    for(int i=0;i<4;i++)
    {
        dx=x+dir[i][0];
        dy=y+dir[i][1];
        if(judge(dx,dy))
        {
            visited[dx][dy]=true;
             dfs(dx,dy);
        }
    }
}
void creat_maze(int a[][3],int i,int j)
{
    int p,q;
    for(p=i*3;p<i*3+3;p++)
    {
        for(q=j*3;q<j*3+3;q++)
        {
            maze[p][q]=a[p-i*3][q-j*3];
        }
    }
}
void wellspring_count()
{
    int i,j;
    for(i=0;i<3*m;i++)
    {
        for(j=0;j<3*n;j++)
        {
            if(maze[i][j]==1&&!visited[i][j])
            {
                wellspring++;
                visited[i][j]=true;
                dfs(i,j);
            }
        }
    }
    printf("%d
",wellspring);
}
void input()
{
    int i,j;
    while(scanf("%d%d",&m,&n),m!=-1||n!=-1)
    {
        memset(visited,false,sizeof(visited));
        wellspring=0;
        char pipe;
        for(i=0;i<m;i++)
       {
           getchar();
        for(j=0;j<n;j++)
        {
            scanf("%c",&pipe);
            switch(pipe)
            {
                case 'A': creat_maze(A,i,j);break;
                case 'B': creat_maze(B,i,j);break;
                case 'C': creat_maze(C,i,j);break;
                case 'D': creat_maze(D,i,j);break;
                case 'E': creat_maze(E,i,j);break;
                case 'F': creat_maze(F,i,j);break;
                case 'G': creat_maze(G,i,j);break;
                case 'H': creat_maze(H,i,j);break;
                case 'I': creat_maze(I,i,j);break;
                case 'J': creat_maze(J,i,j);break;
                case 'K': creat_maze(K,i,j);break;
            }
        }
       }
        wellspring_count();
    }
}

int main()
{
 //   freopen("E:\in.txt","r",stdin);
    input();
    return 0;
}
View Code

但是这是一个并查集专题里的题,所以应该还会有更高效的方法,毕竟我的代码里没有用到并查集。

所以又想了一下,瞬变看了一下别人的并查集思路,又写了一个代码。然而,这次用并查集却死活过不了。。。找bug找了接近两个小时了,自己找的案例都过掉了。。。

先附上wa掉的代码:

#include"iostream"
#include"stdio.h"
#include"string"
#include"string.h"
#include"cmath"
#include"algorithm"
#include"ctype.h"
#include"queue"
#include"stack"
#include"vector"
using namespace std;
const int mx=55;
int maze[mx][mx];
int fa[mx*mx];
int m,n,wellspring;
int dir[4][2]={{0,-1},{-1,0},{0,1},{1,0}};//左上右下
//左上右下有水管接口的用1表示
int farm[11][4]=
{
    {1,1,0,0},
    {0,1,1,0},
    {1,0,0,1},
    {0,0,1,1},
    {0,1,0,1},
    {1,0,1,0},
    {1,1,1,0},
    {1,1,0,1},
    {1,0,1,1},
    {0,1,1,1},
    {1,1,1,1}
};
void Set()
{
    int i;
    for(i=0;i<m*n;i++)
        fa[i]=i;
}

int Find(int x)
{
    int t1,t2=x;
    while(t2!=fa[t2]) t2=fa[t2];
    return t2;
}

void Union(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    if(fx!=fy)
    {
        fa[fx]=fy;
        wellspring--;
    }
}

bool judge(int k,int x,int y)
{
    switch(k)
    {
    case 0:
        if(farm[x][0]&&farm[y][2])
            return true;
        break;
    case 1:
        if(farm[x][1]&&farm[y][3])
            return true;
        break;
    case 2:
        if(farm[x][2]&&farm[y][0])
            return true;
        break;
    case 3:
        if(farm[x][3]&&farm[y][1])
            return true;
        break;
    }
    return false;
}

void Count()
{
    int i,j,k,dx,dy;
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<4;k++)
            {
                dx=i+dir[k][0];
                dy=j+dir[k][1];
                if(dx>=0&&dx<m&&dy>=0&&dy<n)//判定越界条件
                if(judge(k,maze[i][j],maze[dx][dy]))
                    Union(i*m+j,dx*m+dy);
            }
        }
    }
}

void Input()
{
    int i,j;
    while(scanf("%d%d",&m,&n),m>=1&&n>=1)
    {
        Set();
        wellspring=m*n;
        char pipe;
        for(i=0;i<m;i++)
        {
            getchar();
            for(j=0;j<n;j++)
            {
                scanf("%c",&pipe);
                maze[i][j]=pipe-'A';
            }
        }
        Count();
        printf("%d
",wellspring);
    }
}

int main()
{
  //  freopen("E:\in.txt","r",stdin);
    Input();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/acm-jing/p/4660626.html