uva 657 The die is cast(双重搜索)

来源:互联网 发布:java classloader原理 编辑:程序博客网 时间:2024/04/30 08:39

搜索题以前做过几道,有一定的认识,首先这道题的难度是:读不懂题意。。。。闭嘴

看了看网上的题意:好像明白了点,就是说有几块区域,*连通(是四连通,上下左右)的区域代表骰子,其中可能有

字符'X','X'可能叫做点数吧,字符'.'表示背景,不用管,就是让求一共有几块骰子以及他们分别表示的数是多

少,每个骰子区域中'X'的连通个数代表点数,比如题上一共有4个骰子,第一个是两点,第二个是1点,第三个是两

点,第四个是四点,输出按升序就ok了。

思路:

用双重搜索就可以,判断双重连通分量的个数,我用的是两个dfs,第一个是遍历'*'连通图,第二个是遍

历'X'的连通图,遍历'X'后都会把它改为字符'*',之后重新将它作为'*'遍历(刚开始就是在这wa的)忘了重新遍

历了,否则会多算的,因为'X'都是和'*'挨着的,所以每次进去的时候可以都从'*'进去。

代码:

#include<stdio.h>#include<string.h>#include<stdlib.h>char a[55][55];int visit[55][55];int dx[4]={-1,0,0,1};int dy[4]={0,-1,1,0}; int s;int res[100];int cmp(const void *a,const void *b){return *(int *)a-*(int *)b;}void dfs2(int x,int y){void dfs1(int ,int );//声明dfs1函数,好久没声明过了 int i,j;a[x][y] = '*';//如果当前字符为X,访问过后置为* //visit[x][y] = 1;for(i=0; i<4; i++){int xx=x+dx[i];int yy=y+dy[i];if(a[xx][yy]=='X'){dfs2(xx,yy);//把所有的连通的'X'都访问一遍,置为'*' }}return ;}void dfs1(int x,int y){int i,j;visit[x][y]=1;for(i=0; i<4; i++){int xx=x+dx[i];int yy=y+dy[i];if(!visit[xx][yy]&&(a[xx][yy]=='*'||a[xx][yy]=='X')){if(a[xx][yy]=='X'){res[s]++; //每次出现X就说明了有一个连通分量,所以加一,之后必须处理它的连通分量,即调用dfs2 dfs2(xx,yy); dfs1(xx,yy);//此处必须调用一下dfs1,因为前面是把它置为'*',所以要把它作为'*'再搜索一遍 //printf("########################\n"); }elsedfs1(xx,yy);}}return ;}int main(){int m,n,i,j;int cnt = 0;while(scanf("%d%d",&m,&n),(m!=0||n!=0)){cnt++;s = 0;int count1 = 0;memset(visit,0,sizeof(visit));memset(res,0,sizeof(res));for(i=0; i<n; i++)scanf("%s",a[i]);//puts("");///puts("");//for(i=0; i<n; i++){for(j=0; j<m; j++){if(!visit[i][j]&&(a[i][j]=='*')){//printf("x = %d y = %d\n",i,j);count1++;//统计出现了多少*连通量 dfs1(i,j);s++;}}}//for(i=0; i<s; i++)//printf("%d ",res[i]);//puts("");qsort(res, s, sizeof(res[0]), cmp);printf("Throw %d\n",cnt);for(i=0; i<count1; i++){printf("%d",res[i]);if(i!=count1-1)printf(" ");}puts("");puts("");}} 



0 0
原创粉丝点击