https://codeforces.com/problemset/problem/1359/B
思路:可以用bfs搜索每一个连通块,得到每一个连通块的 . 的数量,然后我们再判断是贴一块划算还是贴两块划算,然后这里要注意一下两块的瓷砖只能贴同一行的两个
以下是代码实现:
#include<iostream>
#include<queue>
using namespace std;
char board[110][1010];
int n,m,x,y;
int ny[2]={1,-1};
int nx[2]={0,0};
struct node
{
int x,y;
};
int bfs(int X,int Y)
{
int cnt=1;
board[X][Y]='*';
queue<node>q;
node start,next;
start.x=X,start.y=Y;
q.push(start);
while(!q.empty())
{
start=q.front();
q.pop();
for(int i=0;i<2;i++)
{
int dx=start.x+nx[i];
int dy=start.y+ny[i];
if(1<=dx&&dx<=n&&1<=dy&&dy<=m&&board[dx][dy]=='.')//只能是同一行
{
board[dx][dy]='*';
next.x=dx,next.y=dy;
q.push(next);
cnt++;
}
}
}
return cnt;
}
void solved()
{
cin>>n>>m>>x>>y;
int sum=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>board[i][j];
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(board[i][j]=='.')
{
int cnt=bfs(i,j);
if((y/2)<x)
{
sum+=(cnt/2)*y+(cnt%2)*x;
}
else sum+=cnt*x;
}
}
}
cout<<sum<<endl;
return ;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin>>t;
while(t--)
{
solved();
}
return 0;
}