罗伯特是一位着名的工程师 有一天,老板给了他一项任务。该任务的背景如下:
给定一个由方块组成的地图。有三种块:Wall,Grass和Empty。他的老板想在地图上放置尽可能多的机器人。每个机器人都持有一个激光武器,可同时向四个方向(北,东,南,西)射击。机器人不得不一直呆在最初放置的地方,并一直开火。激光束当然可以通过Grass的网格,但无法通过Wall网格。机器人只能放在空块中。当然老板不希望看到一个机器人伤害另一个机器人。换句话说,两个机器人不得放在一条线上(水平或垂直),除非它们之间有墙。
既然你是一个聪明的程序员和罗伯特最好的朋友之一,他就会请你帮他解决这个问题。也就是说,给定地图的描述,计算可以放置在地图中的最大机器人数。
输入
第一行包含一个整数T(<= 11),它是测试用例的数量。
对于每个测试用例,第一行包含两个整数m和n(1 <= m,n <= 50),它们是映射的行和列大小。然后是m行,每行包含n个字符’#’,’*‘或’o’,分别代表Wall,Grass和Empty。
输出
对于每个测试用例,首先输出一行中的案例编号,格式为:“Case:id”,其中id是测试用例编号,从1开始计数。在第二行只输出可以是的最大机器人数放在那张地图上。
样本输入
2
4 4
o ***
oo#o
*** o
4 4
#ooo
o#oo
oo#o
***#
样本输出
案例:1
3
案例:2
5
解析:构图比较麻烦,将行有空地且能互相攻击的放入A数组,将列的放入B数组,其他还好,有些细节要注意
#include <iostream>
#include<vector>
#include<cstring>
#include <cmath>
using namespace std;
vector <int> f[2505];
char mapa[55][55];
int n,m,t,x=1,y=1,cs,a[55][55],b[55][55],link[2505],z;
bool color[2505];
bool find (int i)
{
for (int j=0;j<f[i].size();j++)
{
if (color[f[i][j]]==0)
{
color[f[i][j]]=1;
int q=link[f[i][j]];
link[f[i][j]]=i;
if (q==0||find(q)) return true;
link[f[i][j]]=q;
}
}
return false;
}
void jm()
{
bool p=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
cin>>mapa[i][j];
if (j==1&&p==1)
{
p=0;
x++;
}
if (mapa[i][j]=='o')
{
a[i][j]=x;
p=1;
z=x;
}
if (mapa[i][j]=='#'&&p==1)
{
x++;
p=0;
}
}
p=0;
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
if (j==1&&p==1)
{
p=0;
y++;
}
if (mapa[j][i]=='o')
{
b[i][j]=y;
p=1;
}
if (mapa[j][i]=='#'&&p==1)
{
y++;
p=0;
}
}
return;
}
void lb ()
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
if (mapa[i][j]=='o')
{
// cout<<a[i][j]<<" "<<b[j][i]<<endl;
f[a[i][j]].push_back(b[j][i]);
}
}
}
int main()
{
cin>>t;
for (int i=1;i<=t;i++)
{
for (int j=1;j<=2504;j++)//一定要循环到这么多,第一次卡了好久
{
f[j].clear();
}
memset(link,0,sizeof(link));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
cin>>n>>m;
x=1;y=1;
jm();
lb();
int ans=0;
for (int j=1;j<=z;j++)
{
memset(color,0,sizeof(color));
ans+=find(j);
}
cout<<"Case :q"<<i<<endl;
cout<<ans<<endl;
}
}