题意:同一行或者列的炮台会被射到,求一个位置设炮台使得其炸掉的炮台最多
ac代码:
#include <bits/stdc++.h>
#include <stdio.h>
#define ff(i,x,y)for(int i=x;i<y+1;i++)
#define fs(i,x,y)for(int i=x;i>y-1;i--)
#define all(x) x.begin(),x.end()
#define Ins(x) inserter(x,x.begin())
using namespace std;
int n,m,p[4010],viscol[2010],visrow[2010],mes[4010],dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
char mp[2010][2010];
vector<int>col[2010],row[2010];
typedef pair<int,int> pii;
bool ppan(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m)
return true;
return false;
}
void bfs(int x,int y)
{
queue<pii>hu;
pii now(x,y);
hu.push(now);
int sum=(col[now.second].size()+row[now.first].size());
sum--;
while(!hu.empty())
{
now=hu.front();
hu.pop();
int ne;
ff(i,0,col[now.second].size()-1)
{
ne=col[now.second][i];
if(!visrow[ne])
{
visrow[ne]=1;
p[ne]=p[x];
ff(j,0,row[ne].size()-1)
if(!viscol[row[ne][j]])
sum++;
hu.push(pii(ne,now.second));
}
}
ff(i,0,row[now.first].size()-1)
{
ne=row[now.first][i];
if(!viscol[ne])
{
viscol[ne]=1;
p[ne+n]=p[x];
ff(j,0,col[ne].size()-1)
if(!visrow[col[ne][j]])
sum++;
hu.push(pii(now.first,ne));
}
}
}
mes[p[x]]=sum;
}
int main()
{
scanf("%d%d",&n,&m);
ff(i,1,n)
{
p[i]=i;
scanf("%s",mp[i]+1);
ff(j,1,m)
{
p[j+n]=j+n;
if(mp[i][j]=='+')
{
col[j].push_back(i);
row[i].push_back(j);
}
}
}
int res=0,posx,posy,hupan=0;
ff(i,1,n)
{
ff(j,1,m)
{
if(!viscol[j]&&!visrow[i]&&mp[i][j]=='+')
{
viscol[j]=1;
visrow[i]=1;
p[j+n]=p[i];
bfs(i,j);
}
}
}
ff(i,1,n)
{
ff(j,1,m)
{
int nownum=0;
if(mp[i][j]=='.')
{
if(p[i]==p[j+n])
nownum=mes[p[i]];
else
nownum=mes[p[i]]+mes[p[j+n]];
}
if(nownum>res)
{
hupan=1;
res=nownum;
posx=i;
posy=j;
}
}
}
if(hupan)
printf("%d\n%d %d",res,posx,posy);
else
printf("0");
return 0;
}
关键:visrow viscol 去标记行列,标记每一个点会超时