这里附上题目链接:President’s Office。
~~手动分割~~
题目
输入格式
第一行:
房间长n,宽m,总统办公桌代表的字符串
接下来2 ~ n+1行,每行输入m列:
房间内的办公桌的颜色(大写字母)。"."为空单元格。
输出格式:
一行一个变量:
求出在总统桌四周相邻的办公桌数量
样例解释
3 4 R
G . B .
. R R .
T T T .
此办公室的总统桌在二排的第二,三列(连起来的并且颜色相同算一个办公桌,此样例总统桌面积为1*2)
那么四周则有办公桌:
TTT(TTT面积为1*3)
B
因此输出2。
~~手动分割~~
思路解析
因为连起来的并且颜色相同的桌子算一个办公桌,所以此题就是让我们寻找桌子联通块。
-
从每张总统桌(单个字符)的四个方向上紧邻的格子出发:
若该格上摆放着与总统桌颜色不同的办公桌, 则
①从此格开始向四周搜索;
②说明总统桌周围的桌子联通块数加一。若该格为空地或者也摆放着一张总统桌,则停止搜索。
~~手动分割~~
解法
1.DFS
AC代码:
#include <stdio.h>
#include <stdlib.h>
char pre_table;//总统桌
int n,m;//棋盘有n行m列
char office_map[101][105];//office_map为办公室地图
int location[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//4个方位
int check(int round,int colume,char color)//检查
{
if(round>=0&&round<n&&colume>=0&&colume<m&&office_map[round][colume]!='.'&&office_map[round][colume]==color&&office_map[round][colume]!=pre_table)//若坐标未越界且
{
return 1;
}
return 0;//返回假值
}
int DFS(int round,int colume,char color)
{
int i,x,y;
if(!check(round,colume,color))
{
return 0;
}
office_map[round][colume]='.';
for(i=0;i<4;i++)//沿四个方向继续搜索
{
x=round+location[i][0];
y=colume+location[i][1];
DFS(x,y,color);
}
return 1;
}
int main()
{
int i,j,k,x,y,sum=0;
//输入数据
scanf("%d%d %c",&n,&m,&pre_table);
for(i=0;i<n;i++)
{
scanf("%s",office_map[i]);
}
//开始搜索
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(office_map[i][j]==pre_table)
{
office_map[i][j]='.';
for(k=0;k<4;k++)
{
x=i+location[k][0];
y=j+location[k][1];
if(DFS(x,y,office_map[x][y]))//若找到一个联通块
{
sum++;
}
}
}
}
}
//输出结果
printf("%d",sum);
return 0;
}
2.BFS
AC代码:
#include <stdio.h>
#include <stdlib.h>
char pre_table;//总统桌
int n,m;//棋盘有n行m列
char office_map[101][105];//office_map为办公室地图
int location[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//4个方位
struct box
{
int x,y;
char color;
}queue[10000];
int check(int round,int colume)//检查
{
if(round>=0&&round<n&&colume>=0&&colume<m)//若坐标未越界
{
return 1;
}
return 0;//返回假值
}
int BFS(int round,int colume,char color)
{
int i,x,y;
int tail=0,head=0;//构建队首、队尾
queue[0].x=round;
queue[0].y=colume;
queue[0].color=color;
tail++;
office_map[round][colume]='.';
while(head<tail)
{
for(i=0;i<4;i++)
{
x=queue[head].x+location[i][0];
y=queue[head].y+location[i][1];
if(check(x,y))
{
if(office_map[x][y]==color)//若该格摆放的桌子颜色与之前相同,则说明它也属于同一个联通块
{
//新结点入队
queue[tail].x=x;
queue[tail].y=y;
office_map[x][y]='.';
tail++;
}
}
}
head++;//所有子结点都入队的头结点出队
}
return 0;
}
int main()
{
int i,j,k,x,y,sum=0;
//输入数据
scanf("%d%d %c",&n,&m,&pre_table);
for(i=0;i<n;i++)
{
scanf("%s",office_map[i]);
}
//开始搜索
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(office_map[i][j]==pre_table)//若该格为总统桌
{
office_map[i][j]='.';//将其变为空地
for(k=0;k<4;k++)//分别尝试从4个方向出发
{
x=i+location[k][0];
y=j+location[k][1];
if(check(x,y))//若坐标未越界
{
if(office_map[x][y]!='.'&&office_map[x][y]!=pre_table)//若该格既不是空地或者也不是一张总统桌
{
sum++;//联通块数加一
BFS(x,y,office_map[x][y]);//开始搜索
}
}
}
}
}
}
//输出结果
printf("%d",sum);
return 0;
}