题目描述:
解题思路:
我们可以把每辆车试做一个点,那么这辆车所能互相攻击到的车辆之间就相当于存在一条边。那么很显然,只有互相不被所有车攻击到的车才能染成不同的颜色,那么也就是说同一连通块中的车辆都能被攻击到,也就是连通块的个数即为最大染色个数。
可以想到,只有具备攻击力的车辆才能进行扩展,才能加入队列,而作为空地的点仅仅相当于类似边的存在,不用加入队列。
接下来就是非常基础的广搜爆搜。
CODE:
#include <bits/stdc++.h>
using namespace std;
int n,m,ans=0;
struct Gar
{
int x,y;
Gar(int xx,int yy):x(xx),y(yy) {}
};
char g[50][50];
bool vis[50][50]={0};
queue<Gar> q;
const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
void bfs(int x,int y)
{
q.push(Gar(x,y));
vis[x][y]=true;
while(!q.empty())
{
Gar u=q.front();
q.pop();
for(int i=0;i<4;i++)
{
int j=1;
while(true)
{
int nx=u.x+dx[i]*j,ny=u.y+dy[i]*j;
//由于车可以攻击到向同行同列位置的车,因此我们的扩展要直线延伸。
if(nx<=0||nx>n||ny<=0||ny>m) break;
if(vis[nx][ny])
{
j++; //延伸到同一方向的下一个
continue;
}
if(g[nx][ny]!='R') //舍弃掉作为空地的点,不能加入队列
{
j++;
continue;
}
q.push(Gar(nx,ny));
vis[nx][ny]=true;
break; //找到一个车辆那么同一直线上后面的车辆就不连通了,于是推出此方向延伸
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>g[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
if(!vis[i][j]&&g[i][j]=='R')
{
ans++; //连通块计数
bfs(i,j);
}
}
cout<<ans;
return 0;
}