(送给)圣诞夜的极光

(送给)圣诞夜的极光

题目描述

圣诞老人回到了北极圣诞区,已经快到12点了。也就是说极光表演要开始了。这里的极光不是极地特有的自然极光景象。而是圣诞老人主持的人造极光。

轰隆隆……烟花响起(来自中国的浏阳花炮之乡)。接下来就是极光表演了。

人造极光其实就是空中的一幅幅n*m的点阵图像。只是因为特别明亮而吸引了很多很多小精灵的目光,也成为了圣诞夜最美丽的一刻。

  然而在每幅n*m的点阵图像中,每一个点只有发光和不发光两种状态。对于所有的发光的点,在空中就形成了美丽的图画。而这个图画是以若干个(s个)图案组成的。对于图案,圣诞老人有着严格的定义:对于两个发光的点,如果他们的曼哈顿距离(对于A(x1,y1)和B(x2,y2),A和B之间的曼哈顿距离为|x1-x2|+|y1-y2|)小于等于2。那么这两个点就属于一个图案…… 小精灵们一边欣赏着极光,一边数着每一幅极光图像中的图案数。伴着歌声和舞蹈,度过了美丽的圣诞之夜。^_^

输入输出格式

输入格式:

第一行,两个数n和m。

接下来一共n行,每行m个字符。对于第i行第j个字符,如果其为“-”,那么表示该点不发光,如果其为“#”,那么表示该点发光。不可能出现其他的字符。

输出格式:

第一行,一个数s。

输入输出样例

输入样例#1:

19 48

------------------------------------------------

---####-----#-----#----------------------####---

--######----#-----#---------------------######--

-########--#-#---#-#####--#-##-##---#--########-

-###--###--#-#---#-#----#-##-##--#--#--###--###-

-###--###--#--#-#--######-#--#---#-#---###--###-

-########--#--#-#--#------#--#----##---########-

--######---#---#---######-#--#-----#----######--

---####----------------------------#-----####---

----------------------------------#-------------

------------------------------------------------

---###--#--------#------#-----------------------

--#---#-#---------------#-----------------------

-#------#-##--#-##--##-###-#-##-###--###-#--##--

-#------##--#-##-#-#----#--##--#---##---##-#----

-#------#---#-#--#--#---#--#---#---##----#--#---

--#---#-#---#-#--#---#--#--#---#---##---##---#--

---###--#---#-#--#-##---#--#---#---#-###-#-##---

------------------------------------------------

输出样例#1:

4

说明

1<=n,m<=100

Vijos P1051    洛谷 P1454    小视野 广搜-C

---------------------------------------------------------------------------------------------------------------------------------

讲解:

这道题一看,各位读者就知道是DFS求连通图,水~,在此贴出DFS的代码和BFS的代码以及编者自己歪歪出的并查集代码。

代码实现:

DFS

#include<iostream>

using namespace std;

const int nx[13]={0,1,-1,0,0,2,-2,0,0,1,-1,1,-1};

const int ny[13]={0,0,0,1,-1,0,0,2,-2,-1,1,1,-1};//方向数组

char a[1001][1001];

int n,m,ans;

void dfs(int x,int y)

{

         int i;

         if(x<1 || x>n || y<1 || y>m || a[x][y]!='#') return;//越界或已走过就return

    a[x][y]='-';//标记已走过

    for(i=1;i<=12;i++) dfs(x+nx[i],y+ny[i]);

}

int main()

{

         int i,j;

    scanf("%d%d",&n,&m);

    for(i=1;i<=n;i++) for(j=1;j<=m;j++) cin>>a[i][j];

    for(i=1;i<=n;i++)

         {

        for(j=1;j<=m;j++)

                   {

            if (a[i][j]=='#')

                            {

                ans++;

                dfs(i,j);

            }

        }

    }

    cout<<ans;

}
View Code

BFS

#include<iostream>

#include<queue>

#include<cstring>

#include<cmath>

using namespace std;

char a[101][101];

int book[101][101],n,m;

struct note{int x,y;};

void bfs(int x,int y)

{  

    int tx,ty,k;

    int next[12][2]={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1},{-2,0},{0,-2},{0,2},{2,0}};

    queue<note>q;

    note z;

    q.push((note){x,y});

    book[x][y]=1;

    while(!q.empty())

    {  

        z=q.front();

        for(k=0;k<12;k++)

        {  

            tx=z.x+next[k][0];

            ty=z.y+next[k][1];

            if(tx<1||tx>n||ty<1||ty>m)  continue;

            if(a[tx][ty]=='#'&&book[tx][ty]==0)

            {  

                book[tx][ty]=1;

                q.push((note){tx,ty});

            }

        }

        q.pop();

    }

    return;

}

int main()

{  

    int i,j,ans=0;

    scanf("%d%d\n",&n,&m);//编者实测,没有\n你会wa(wrong answer)

    for(i=1;i<=n;i++) gets(a[i]+1);//没有你会tle(超时)

    for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(a[i][j]=='#'&&!book[i][j]) bfs(i,j),ans++;

    cout<<ans;   

}
View Code

并查集:

#include<cstdio>

#include<iostream>

#include<cstring>

#include<cmath>

#include<algorithm>

using namespace std;

const int inf=110;

int a[inf][inf],n,m,ans,i,j,f[(inf+1)*(inf+1)];

int gets(int x)

{

    if(f[x]==x) return x;

    return f[x]=gets(f[x]);

}

void ff(int x,int y)

{

    int t1=gets(x),t2=gets(y);

    f[t1]=t2;

    return;

}

int main()

{

    char ch[inf];

    scanf("%d%d",&n,&m);

    for(i=1;i<=(n+1)*(inf+1)+(m+1);i++) f[i]=i;

    for(i=1;i<=n;i++)

    {

        scanf("%s",&ch);

        for(j=1;j<=m;j++)

        {

            if(ch[j-1]=='-') a[i][j]=0;

            else a[i][j]=1;   

        }

    }

    for(i=1;i<=n;i++)

    {

             for(j=1;j<=m;j++)

             {

                       if(a[i][j]==0) continue;

            if(i-1>=1 && a[i-1][j]!=0) ff((i-1)*inf+j,i*inf+j);

            if(i-2>=1 && a[i-2][j]!=0) ff((i-2)*inf+j,i*inf+j);

            if(i+1<=n && a[i+1][j]!=0) ff((i+1)*inf+j,i*inf+j);

            if(i+2<=m && a[i+2][j]!=0) ff((i+2)*inf+j,i*inf+j);

            if(j-1>=1 && a[i][j-1]!=0) ff(i*inf+(j-1),i*inf+j);

            if(j-2>=1 && a[i][j-2]!=0) ff(i*inf+(j-2),i*inf+j);

            if(j+1<=m && a[i][j+1]!=0) ff(i*inf+(j+1),i*inf+j);

            if(j+2<=m && a[i][j+2]!=0) ff(i*inf+(j+2),i*inf+j);

            if(i-1>=1 && j-1>=1 && a[i-1][j-1]!=0) ff((i-1)*inf+(j-1),i*inf+j);

            if(i-1>=1 && j+1<=m && a[i-1][j+1]!=0) ff((i-1)*inf+(j+1),i*inf+j);

            if(i+1<=n && j-1>=1 && a[i+1][j-1]!=0) ff((i+1)*inf+(j-1),i*inf+j);

            if(i+1<=n && j+1<=m && a[i+1][j+1]!=0) ff((i+1)*inf+(j+1),i*inf+j);

        }

    }

    for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(f[i*inf+j]==i*inf+j && a[i][j]!=0) ans++;

    printf("%d",ans);

    return 0;

}
View Code
posted @ 2018-02-12 18:16  欢语_暗影  阅读(334)  评论(0)    收藏  举报