P10379 [GESP202403 七级] 俄罗斯方块

题目

传送门

思路

不同的定义

是两个方块种类不同为两个方块形状不相同,颜色随意。

方块的定义

是几个相邻且颜色相同的点组成的连通块。

寻找连通块

我们遍历整个数组,但这个f[i][j]==false也就是没有被标记过时我们可以使用BFS或DFS来寻找连通块

如何判断不同种类!!!

这个是这道题唯一的难点,我运用了一种类似于哈希的思想,将每个结点减去连通块的最小的x和最小的y,然后我们就定义一个set来去重,然后就可以快乐了AC了

代码

有注释

#include<bits/stdc++.h>
using namespace std;
const int N=505;  
int n,m;
int a[N][N]; 
bool f[N][N];
int zx[6]={0,1,0,-1};//方向数组 
int zy[6]={1,0,-1,0};//方向数组 
set<vector<pair<int,int> > > s;//set去重 

int main(){
	std::ios::sync_with_stdio(false);//关闭输入输出流 
	std::cin.tie(0);
	std::cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(!f[i][j]){//如果没有被标记过,也就是发现了新的连通块 
				f[i][j]=true;//标记 
				queue<pair<int,int> > q;
				vector<pair<int,int > >v; 
				v.push_back({i,j});
				q.push({i,j});
				while(!q.empty()){//BFS
					int tx=q.front().first;
					int ty=q.front().second;
					q.pop();
					for(int i=0;i<4;i++){
						if(tx+zx[i]>=1&&tx+zx[i]<=n&&ty+zy[i]>=1&&ty+zy[i]<=m&&f[tx+zx[i]][ty+zy[i]]==false&&a[tx][ty]==a[tx+zx[i]][ty+zy[i]]){
							f[tx+zx[i]][ty+zy[i]]=true;
							q.push({tx+zx[i],ty+zy[i]});
							v.push_back({tx+zx[i],ty+zy[i]});
						}
					}
				}
				int mix=n,miy=m; 
				for(int i=0;i<v.size();i++){//选择最小的x和y 
					mix=min(mix,v[i].first);
					miy=min(miy,v[i].second);
				}
				for(int i=0;i<v.size();i++){//每个结点都减去最小的x和y 
					v[i].first=v[i].first-mix;
					v[i].second=v[i].second-miy;
				}
				sort(v.begin(),v.end());//排序保证唯一性 
				s.insert(v);//加入set 
			}
		}
	}
	cout<<s.size();//set的长度就是种类 
	return 0;
}

无注释

#include<bits/stdc++.h>
using namespace std;
const int N=505;  
int n,m;
int a[N][N]; 
bool f[N][N];
int zx[6]={0,1,0,-1};
int zy[6]={1,0,-1,0};
set<vector<pair<int,int> > > s;

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(!f[i][j]){
				f[i][j]=true;
				queue<pair<int,int> > q;
				vector<pair<int,int > >v; 
				v.push_back({i,j});
				q.push({i,j});
				while(!q.empty()){
					int tx=q.front().first;
					int ty=q.front().second;
					q.pop();
					for(int i=0;i<4;i++){
						if(tx+zx[i]>=1&&tx+zx[i]<=n&&ty+zy[i]>=1&&ty+zy[i]<=m&&f[tx+zx[i]][ty+zy[i]]==false&&a[tx][ty]==a[tx+zx[i]][ty+zy[i]]){
							f[tx+zx[i]][ty+zy[i]]=true;
							q.push({tx+zx[i],ty+zy[i]});
							v.push_back({tx+zx[i],ty+zy[i]});
						}
					}
				}
				int mix=n,miy=m; 
				for(int i=0;i<v.size();i++){
					mix=min(mix,v[i].first);
					miy=min(miy,v[i].second);
				}
				for(int i=0;i<v.size();i++){
					v[i].first=v[i].first-mix;
					v[i].second=v[i].second-miy;
				}
				sort(v.begin(),v.end());
				s.insert(v);
			}
		}
	}
	cout<<s.size();
	return 0;
}

码需慢慢打,心急则味散

posted @ 2026-08-22 23:30  陈晨2011  阅读(7)  评论(0)    收藏  举报