题解:CF31D Chocolate
bfs。
思路
总体来说:暴力删边,暴力搜索。
删边
首先不难发现:
(注意下面的图左上角的格子是
切掉一条横向边相当于把这条线上面的点和下面的点的连接切断了。
具体来说,我们假设这条线段的横坐标为
如果这条线段是纵向的,同理,设这条线段的纵坐标为
那么问题转移到了如何实现删边上。
我们可以开一个数组 go
),其中
,向右。 ,向左。 ,向上。 ,向下。
有了这个数组之后,不难发现切断横向边就是假设这条线段的横坐标为
然后暴力 bfs 即可。因为每个点至多遍历一次,所以是
#include<bits/stdc++.h>
using namespace std;
int n,m,q,go[505][505][5],vis[505][505],cnt,ans[250005],sum;
const int dx[5]={0,0,0,-1,1};
const int dy[5]={0,1,-1,0,0};
queue<int>q1,q2;
void bfs(int x,int y){
q1.push(x);
q2.push(y);
vis[x][y]=1;
while(!q1.empty()){
x=q1.front();
y=q2.front();
sum++;
q1.pop();
q2.pop();
for(int i=1;i<=4;i++){
if(go[x][y][i])continue;
int nx=x+dx[i],ny=y+dy[i];
if(nx<=0||nx>n||ny<=0||ny>m)continue;
if(vis[nx][ny])continue;
vis[nx][ny]=1;
q1.push(nx);
q2.push(ny);
}
}
}
int main(){
cin>>n>>m>>q;
for(int i=1;i<=q;i++){
int x1,y1,x2,y2;
cin>>x1>>y1>>x2>>y2;
if(x1==x2){
for(int j=y1+1;j<=y2;j++){
go[x1][j][4]=1;
go[x1+1][j][3]=1;
}
}
else{
for(int j=x1+1;j<=x2;j++){
go[j][y1][1]=1;
go[j][y1+1][2]=1;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!vis[i][j]){
bfs(i,j);
ans[++cnt]=sum;
sum=0;
}
}
}
sort(ans+1,ans+cnt+1);
for(int i=1;i<=cnt;i++)if(ans[i]!=0)cout<<ans[i]<<' ';
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】