題目連接:http://acm.pku.edu.cn/JudgeOnline/problem?id=1979
1979:Red and Black
具体要求:
输入相应的格子的数目,并且标记每个格子的颜色,当遇到黑色的格子时可以踩上,当遇到红色的格子时不能踩上,要求输出从一个起始点出发能够踩到的黑色格子数。
算法思想:
1,可以根据图的深度优先搜索,计算并输出通过深度搜索所通过的节点数,即相应的格子数目。
2,可以根据图的广度优先搜索,计算并输出通过广度搜索所通过的节点数,即相应的格子数目。
算法实现:
1,深度优先搜索:通过递归方法,从图结构的一个结点开始深度搜索。相应的代码如下
struct save {
char c;
int flag; //设立标志点
}tu[21][21]; //存储结构
void expand(int x,int y) //节点的扩展
{
if(tu[x-1][y].c=='.') //向上探测,并将符合要求的节点入队列
if(tu[x-1][y].flag)
{
count++; // 计数
tu[x-1][y].flag=0; //标志已走过
expand(x-1,y);
}
。。。。
}
主函数
int main(){
int i,j,x,y,n,m;
while(scanf("%d%d", &n, &m ))
{
getchar();
if(m==0&&n==0)
break;
count=1;
for(i=0;i<21;i++)
for(j=0 ; j<21 ; j++)
{
tu[i][j].c=0;
tu[i][j].flag=1;
} //二维数组的初始化
for (i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
scanf("%c",&tu[i][j].c);
if(tu[i][j].c=='@')
{
x=i;
y=j;
}
}
getchar();
}
expand(x,y);
printf("%d\n",count);
}
return 0;
}
广度优先搜索:通过建立队列实现广度搜索,每走到符合要求的格子时,当前格子进队列。相应的代码如下
存储结构:
char tu[21][21];
int head,tail,count;
struct save {
int x;
int y;
}check[400]; //队列
int judge(int x,int y) //判断是否已经走过这个格子
{
int i;
for (i=0;i<tail;i++)
if(x==check[i].x&&y==check[i].y)
return 0;
return 1;
}
void expand(int x,int y) //节点的扩展
{
if(tu[x-1][y]=='.') //向上探测,并将符合要求的节点入队列
if(judge(x-1,y))
{
count++;
check[tail].x=x-1,check[tail].y=y;
tail++;
}
。。。。。。
}
主函数
int main(){
int i,j,x,y,n,m;
while(scanf("%d%d", &n, &m ))
{
getchar();
if(m==0&&n==0)
break;
head=0;
tail=0;
count=1;
for(i=0;i<21;i++)
for(j=0 ; j<21 ; j++)
tu[i][j]=0;
for (i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
{
scanf("%c",&tu[i][j]);
if(tu[i][j]=='@')
{
x=i;
y=j;
}
}
getchar();
}
check[tail].x=x,check[tail].y=y;
tail++;
while (head<tail)//开始搜索
{
expand(check[head].x,check[head].y);
head++;
}
printf("%d\n",count);
}
return 0;
}
做题心得:
这道题目参考了网上的一些代码,不过以上两个算法是建立在看懂了后得到思路后编写的。同过这道题目,进一步熟悉了图的深度优先搜索的思想。