题解 SP15436 【UCV2013H - Slick】

Chinshyo

2020-10-12 23:03:46

Solution

这是一道非常经典的**铺地板问题**。说起铺地板,最优选择的就是DFS。让我们来看一下解题思路: # 搜索过程 首先要明确这道题的求解搜索过程。首先把整张地图用for双重循环扫一遍,每次发现有墨水就开始从该点出发向四周扩展开去。然后,每经过一个点都把该点的墨水消除,或者是标记为已访问过。 ![](https://cdn.luogu.com.cn/upload/image_hosting/6sr5za91.png?x-oss-process=image/resize,m_lfit,h_170,w_225) 如果该点是墨水就可以被访问: ![](https://cdn.luogu.com.cn/upload/image_hosting/htdgjemz.png?x-oss-process=image/resize,m_lfit,h_170,w_225) # 输入输出优化 本题输入输出较多,建议使用输入输出优化,本人建议使用这行代码关闭同步流 ```cpp ios::sync_with_stdio(false); ``` # CODE ```cpp #include<bits/stdc++.h> using namespace std; int a[255][255]; int n,m,ans; void dfs(int dep,int i,int j) { ans++; a[i][j]=0; if(a[i+1][j]==1) dfs(dep+1,i+1,j); if(a[i][j+1]==1) dfs(dep+1,i,j+1); if(a[i-1][j]==1) dfs(dep+1,i-1,j); if(a[i][j-1]==1) dfs(dep+1,i,j-1); } int main() { ios::sync_with_stdio(false); int n,m,k,q; cin>>n>>m; memset(a,0x3f,sizeof(a)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>a[i][j]; } } cin>>k>>q; map <int,int> ma; int answer=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]==1) { ans=0; dfs(1,i,j); if(ma.find(ans)!=ma.end()) { ma.find(ans)->second++; } else { ma.insert(make_pair(ans,1)); } } } } for(map<int,int>::iterator i=ma.begin();i!=ma.end();i++) { answer=answer+i->second; } cout<<answer<<endl; for(map<int,int>::iterator i=ma.begin();i!=ma.end();i++) { cout<<i->first<<" "<<i->second<<endl; } return 0; } ```