求hack数据
查看原帖
求hack数据
1030758
fengzhenxiu楼主2024/6/5 23:13

思路是把一个联通块的所有点放到一个集合中(用并查集实现)同时算出该联通块的气,代码只有43分,求hack数据

#include <iostream>
using namespace std;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
const int N=2e3+5,M=2e3+5;
int t,n,m,Map[N][M];
int f[N*M],c[N*M];
int find(int x) {
	if(x==f[x]) return x;
	else return f[x]=find(f[x]);
}
bool vis[N*M];
bool check() {
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) {
		f[(i-1)*m+j]=(i-1)*m+j; c[(i-1)*m+j]=0;
		vis[(i-1)*m+j]=false;
	}
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) {
		if(Map[i][j]==1) {
			for(int k=0;k<4;k++) {
				int x=i+dx[k],y=j+dy[k];
				if(Map[x][y] or x==0 or y==0 or x>n or y>m) continue;
				else Map[x][y]=2;
				int u=find((x-1)*m+y);
				for(int d=0;d<4;d++) {
					int p=x+dx[d],q=y+dy[d];
					if(p==0 or q==0 or p>n or q>m) continue;
					int v=find((p-1)*m+q);
					if(Map[p][q]==0) c[u]++;
					else if(Map[p][q]==2) {
						c[u]+=c[v]-1;
						f[v]=u;
					}
				}
			}
		}
	}
	int cnt=0;
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(Map[i][j]==2) {
		//cout<<i<<' '<<j<<endl;
		int node=find((i-1)*m+j);
		if(!vis[node]) {
			vis[node]=true;
			cnt+=(c[node]==0);
		}
	}
	//cout<<cnt<<endl;
	return cnt>1;
}
int main() {
	cin>>t;
	while(t--) {
		cin>>n>>m;
		for(int i=1;i<=n;i++) Map[i][0]=Map[i][m+1]=1;
		for(int j=1;j<=m;j++) Map[0][j]=Map[n+1][j]=1;
		for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) {
			char ch; cin>>ch;
			if(ch=='*') Map[i][j]=1;
			else Map[i][j]=0;
		}
		if(check()) cout<<"YES";
		else cout<<"NO";
		cout<<endl;
	}
	return 0;
}
2024/6/5 23:13
加载中...