悬赏10元!
  • 板块CF1799E City Union
  • 楼主wxzzzz
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/11/8 15:13
  • 上次更新2023/11/8 17:57:11
查看原帖
悬赏10元!
749630
wxzzzz楼主2023/11/8 15:13

简短且通俗易懂。

#include <bits/stdc++.h>
#define ll long long
#define rll register ll
#define cll const ll
#define N 55
#define M 2505
using namespace std;
inline ll read()
{
    rll x=0;bool f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-') f=0;c=getchar();}
    while(c>=48&&c<=57){x=x*10+(c^48);c=getchar();}
    return f?x:-x;
}
inline void write(ll x)
{
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+48);
}
cll dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
ll t=read(),n,m,nx,ny,idx,root,minn,minl,maxr,f[M],id[M],maxx[M],maxy[M],minx[M],miny[M];
char s[N][N];
bool check;
bitset<M> vis,flag;
inline ll p(ll x,ll y){return (x-1)*m+y;}
inline ll find(ll x)
{
	if(x==f[x]) return x;
	return f[x]=find(f[x]);
}
inline bool ok()
{
	rll last=0;
	for(rll i=1;i<=n;i++)
	{
		for(rll j=1;j<=m;j++)
		{
			if(s[i][j]=='#')
			{
				if(last&&find(p(i,j))!=last) return 0;
				last=find(p(i,j));
			}
		}
	}
	return 1;
}
inline void line()
{
	for(rll i=1;i<=n;i++)
	{
		minl=0,maxr=0;
		for(rll j=1;j<=m;j++)
		{
			if(s[i][j]=='#'&&!minl) minl=j;
			if(s[i][j]=='#') maxr=j;
		}
		if(!minl) continue;
		for(rll j=minl,last=0;j<=maxr;j++)
		{
			if(s[i][j]=='.')
			{
				check=1,s[i][j]='#';
				if(last) f[find(p(i,j))]=last;
				last=find(p(i,j));
			}
		}
	}
}
inline void dfs(ll x,ll y)
{
	vis[p(x,y)]=1,f[p(x,y)]=root;
	for(rll i=0;i<4;i++)
	{
		cll nx=x+dx[i],ny=y+dy[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&!vis[p(nx,ny)]&&s[nx][ny]=='#')
			dfs(nx,ny);
	}
}
inline void row()
{
	for(rll j=1;j<=m;j++)
	{
		minl=0,maxr=0;
		for(rll i=1;i<=n;i++)
		{
			if(s[i][j]=='#'&&!minl) minl=i;
			if(s[i][j]=='#') maxr=i;
		}
		if(!minl) continue;
		for(rll i=minl,last=0;i<=maxr;i++)
			if(s[i][j]=='.')
				check=1,s[i][j]='#';
	}
}
int main()
{
    while(t--)
    {
    	n=read(),m=read(),idx=0,minn=1e18,check=1;
		vis.reset(),flag.reset();
		memset(maxx,0,sizeof maxx);
		memset(maxy,0,sizeof maxy);
		memset(minx,0x3f,sizeof minx);
		memset(miny,0x3f,sizeof miny);
    	for(rll i=1;i<=n;i++)
    		scanf("%s",s[i]+1);
    	for(rll i=1;i<=n;i++)
    		for(rll j=1;j<=m;j++)
    			f[p(i,j)]=p(i,j);
    	while(check) check=0,line(),row();
    	for(rll i=1;i<=n;i++)
    		for(rll j=1;j<=m;j++)
    			if(s[i][j]=='#'&&!vis[p(i,j)])
					root=p(i,j),dfs(i,j);
    	if(ok())
    	{
			for(rll i=1;i<=n;i++)
				printf("%s\n",s[i]+1);
			putchar('\n');
			continue;
		}
    	for(rll i=1;i<=n;i++)
    	{
    		for(rll j=1,now;j<=m;j++)
    		{
    			if(s[i][j]=='.') continue;
    			now=find(p(i,j));
    			if(!flag[now]) id[++idx]=now,flag[now]=1;
    			minx[now]=min(minx[now],i);
				miny[now]=min(miny[now],j);
    			maxx[now]=max(maxx[now],i);
    			maxy[now]=max(maxy[now],j);
			}
		}
//		cout << "id1=" << id[1] << ' ' << "id2=" << id[2] << "\nSB:\n";
//		for(rll i=1;i<=2;i++)
//			cout << minx[id[i]] << ' ' << miny[id[i]] << ' ' << maxx[id[i]] << ' ' << maxy[id[i]] << '\n';
		if(maxy[id[1]]<maxy[id[2]])
		{
			if(maxx[id[1]]<maxx[id[2]])  //1在2的左上角
			{
//				cout << "op1\n";
				nx=maxx[id[1]],ny=maxy[id[1]],s[nx][ny]='#';
//				cout << "st=" << nx << ' ' << ny << '\n';
				while(nx<minx[id[2]]||ny<maxy[id[2]])
				{
					if(nx<minx[id[2]]) nx++;
					s[nx][ny]='#';
					if(ny<maxy[id[2]]) ny++;
					s[nx][ny]='#';
				}
			}
			else                         //1在2的右上角
			{
//				cout << "op2\n";
				nx=minx[id[1]],ny=maxy[id[1]],s[nx][ny]='#';
//				cout << "st=" << nx << ' ' << ny << '\n';
				while(nx>maxx[id[2]]||ny<maxy[id[2]])
				{
					if(nx>maxx[id[2]]) nx--;
					s[nx][ny]='#';
					if(ny<maxy[id[2]]) ny++;
					s[nx][ny]='#';
				}
			}
		}
		else
		{
			if(maxx[id[1]]<maxx[id[2]])  //1在2的左下角
			{
//				cout << "op3\n";
				nx=maxx[id[1]],ny=miny[id[1]],s[nx][ny]='#';
//				cout << "st=" << nx << ' ' << ny << '\n';
				while(nx<minx[id[2]]||ny<maxy[id[2]])
				{
					if(nx<minx[id[2]]) nx++;
					s[nx][ny]='#';
					if(ny<maxy[id[2]]) ny++;
					s[nx][ny]='#';
				}
			}
			else                         //1在2的右下角
			{
//				cout << "op4\n";
				nx=minx[id[1]],ny=miny[id[1]],s[nx][ny]='#';
//				cout << "st=" << nx << ' ' << ny << '\n';
				while(nx>maxx[id[2]]||ny>maxy[id[2]])
				{
					if(nx>maxx[id[2]]) nx--;
					s[nx][ny]='#';
					if(ny>maxy[id[2]]) ny--;
					s[nx][ny]='#';
				}
			}
		}
		check=1;
    	while(check) check=0,line(),row();
		for(rll i=1;i<=n;i++)
			printf("%s\n",s[i]+1);
		putchar('\n');
	}
    return 0;
}
2023/11/8 15:13
加载中...