CF2057G Secret Message 题解
这个题目限制给的
考虑如下 trick:如果我们不考虑这个限制的情况下构造出了
这也太牛了!那我们怎么找到这五个方案呢?
考虑一种十字形的密铺:
发现,如果我们选择了所有十字形中心,那么剩余未被影响到的格子就会在边上,我们在另外选择这些点即可。
注意到这些十字形中心的坐标
#include<bits/stdc++.h>
#define N 2000005
#define id(X,Y) ((X-1)*m+(Y))
#define ll long long
#define mod
using namespace std;
int n,m,a[N],col[N],vis[N];
void sol()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int id=id(i,j);
col[id]=(i+j*2)%5;
char c;
cin>>c;
a[id]=c=='#';
vis[id]=0;
}
}
int lim=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int id=id(i,j);
if(!a[id]) continue;
lim++;
lim+=i==n||!a[id(i+1,j)];
lim+=j==m||!a[id(i,j+1)];
lim+=i==1||!a[id(i-1,j)];
lim+=j==1||!a[id(i,j-1)];
}
}
lim/=5;
for(int c=0;c<5;c++)
{
vector<int>vec;
fill(vis+1,vis+n*m+1,0);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int id=id(i,j);
if(!a[id]||col[id]!=c) continue;
vis[id]=1;
vec.push_back(id);
if(i<n) vis[id(i+1,j)]=1;
if(j<m) vis[id(i,j+1)]=1;
if(i>1) vis[id(i-1,j)]=1;
if(j>1) vis[id(i,j-1)]=1;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int id=id(i,j);
if(!a[id]||vis[id]) continue;
vec.push_back(id);
}
}
if(vec.size()>lim) continue;
fill(vis+1,vis+n*m+1,0);
for(auto k:vec) vis[k]=1;
break;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int id=id(i,j);
cout<<(vis[id]?'S':a[id]?'#':'.');
}
cout<<'\n';
}
}
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while(t--) sol();
return 0;
}