洛谷 P1162 填涂颜色
作者:互联网
菜鸟生成记(34)
思路:
(1)双层for循环逐点访问
(2)bfs判断该点是否在圈内(被1包围的圈内0,其行坐标和列坐标不可能为0,或n-1(n最大行列数))
(3)然后dfs将该点能够到达的所有点染色(赋值2),同时每个点被访问后,做标记,减少后续不必要的重复访问;
推荐使用STL 队列,我使用手工队列超时了;
AC代码(用到了vector queue队列,下面84分没用队列,一个点超时了;两个代码的思路是一样的,就是一个用了STL 队列,一个用的是手工 队列(超时了))
#include<bits/stdc++.h>
using namespace std;
struct st{//结构体
int x,y;
};
vector<vector<int> >a;//二维数组(vector容器)
int book[100][100]={0};//标记数据
int n;//行列长度(定义为全局变量,写函数时可以少写一个参数)
int next1[4][2]={1,0,0,1,-1,0,0,-1};//方向数组
void dfs(int x,int y)//深搜染色
{
a[x][y]=2;
int nx,ny;
for(int i=0;i<4;i++)
{
nx=x+next1[i][0];
ny=y+next1[i][1];
if(nx>=n||nx<0||ny>=n||ny<0)
continue;
if(a[nx][ny]==0)
dfs(nx,ny);//递归染色
}
}
int bfs(int x,int y)//广搜判断该点是否在圈内
{
st t;//定义一个结构体变量
int nx,ny,x1,y1;
queue<st> q;//队列(队列里的每个元素都是一个结构体变量)
t.x=x;//结构体变量赋值
t.y=y;
if(x==n-1||y==0||y==n-1||x==0)//在圈内的0,是不可能出现在边缘部分(0,n-1,也就是说行和列坐标不会是0,或者n-1)
return 0;//返回0,不在圈内
book[x][y]=1;//标记
q.push(t);//入队
while(q.size()!=0)//判断队列是否空,也可以!q.empty()
{
t=q.front();//访问队首元素
nx=t.x;
ny=t.y;
q.pop();//队首元素出队
for(int i=0;i<4;i++)
{
x1=nx+next1[i][0];
y1=ny+next1[i][1];
if(book[x1][y1]==0&&a[x1][y1]==0)
{
if(x1==n-1||x1==0||y1==n-1||y1==0)//在圈内的0,是不可能出现在边缘部分(0,n-1,也就是说行和列坐标不会是0,或者n-1)
return 0;//返回0,不在圈内
book[x1][y1]=1;
t.x=x1;
t.y=y1;
q.push(t);//入队
}
}
}
return 1;//在圈内返回1
}
int main()
{
vector<int>t;
int flag=0;
cin>>n;
for(int i=0;i<n;i++)//输入二维数组
{
t.clear();
for(int j=0;j<n;j++)
{
int s;
cin>>s;
t.push_back(s);//单个元素入栈
}
a.push_back(t);//一组元素入栈
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i][j]==0&&book[i][j]==0)//减少不必要的循环
{
if(bfs(i,j)==1)//判断是否在圈内(返回1:在圈内;返回0:在圈外)
{
dfs(i,j);//在圈内染色(圈内0全部赋值2)
flag=1;
break;
}
}
}
if(flag==1)//减少不必要的循环
break;
}
for(int i=0;i<n;i++)//输出
{
for(int j=0;j<n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
84分超时代码;
#include<bits/stdc++.h>
using namespace std;
struct st{
int x,y;
};
vector<vector<int> >a;
int book[100][100]={0};
int n,f[100][100]={0};
int next1[4][2]={1,0,0,1,-1,0,0,-1};
void dfs(int x,int y)
{
a[x][y]=2;
int nx,ny;
for(int i=0;i<4;i++)
{
nx=x+next1[i][0];
ny=y+next1[i][1];
if(nx>=n||nx<0||ny>=n||ny<0)
continue;
if(a[nx][ny]==0)
dfs(nx,ny);
}
}
int bfs(int x,int y)
{
st q[100];
int f=0,r=0;
int nx,ny,a1,a2;
q[r].x=x;
q[r++].y=y;
if(x==n-1||y==0||y==n-1||x==0||book[x][y]==1)
return 0;
book[x][y]=1;
while(f!=r)
{
nx=q[f].x;
ny=q[f++].y;
for(int i=0;i<4;i++)
{
a1=nx+next1[i][0];
a2=ny+next1[i][1];
if(book[a1][a2]==0&&a[a1][a2]==0)
{
if(a1==n-1||a1==0||a2==n-1||a2==0)
return 0;
book[a1][a2]=1;
q[r].x=a1;
q[r++].y=a2;
}
}
}
return 1;
}
int main()
{
vector<int>t;
int flag=0;
cin>>n;
for(int i=0;i<n;i++)
{
t.clear();
for(int j=0;j<n;j++)
{
int s;
cin>>s;
t.push_back(s);
}
a.push_back(t);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if(a[i][j]==0&&book[i][j]==0)
{
if(bfs(i,j)==1)
{
dfs(i,j);
flag=1;
break;
}
}
}
if(flag==1)
break;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}
标签:填涂,洛谷,int,nx,ny,book,next1,P1162,圈内 来源: https://blog.csdn.net/Thy__father/article/details/115003682