P3958 [NOIP2017 提高组] 奶酪
思路是,先把一部分从下表面进去的洞输进去队列,再开始bfs往下推进,用v[i]表示是否走过,然后两个结构体,一个代表第几组数据,另一个代表数据下的空洞坐标。
#include<bits/stdc++.h>
using namespace std;
int v[1005];
struct sb
{
long long n,h,r;
}arr[25];
struct stp
{
long long x,y,z;
}aff[1005];
double dist(stp a,stp b)
{
double m;
m=sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2)+pow(a.z-b.z,2));
return m;
}
void bfs(int d)
{
aff[0].x=aff[0].y=aff[0].z=0;
queue<stp> xu;
for(int i=1;i<=arr[d].n;i++)
{
if(aff[i].z<=arr[d].r) {
xu.push(aff[i]);
v[i]=1;}}
while(xu.empty()!=1)
{
aff[0]=xu.front();
if(aff[0].z+arr[d].r>=arr[d].h)
{
cout<<"Yes"<<endl;
return ;
}
for(int i=1;i<=arr[d].n;i++)
{
if(dist(aff[0],aff[i])<=1.0*2*arr[d].r)
{
if(v[i]==0) {v[i]=1;
xu.push(aff[i]);
}
}
}
xu.pop();
}
cout<<"No"<<endl ;
return;
}
int main()
{ memset(v,0,sizeof(v));
int t;
cin>>t;
for(int g=1;g<=t;g++)
{
cin>>arr[g].n>>arr[g].h>>arr[g].r;
for(int j=1;j<=arr[g].n;j++)
{
cin>>aff[j].x>>aff[j].y>>aff[j].z;
}
memset(v,0,sizeof(v));
bfs(g);
}
}
P1162 填涂颜色
思路是,反其道而行之,只bfs最外面一圈的数,然后碰到1停止,没碰到1之前所有的0都对一个所对应数组的值改变,从而区分出圈内外的0.
#include<bits/stdc++.h>
using namespace std;
struct qq
{
int x,y;
};
int a[40][40];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int v[40][40];
qq ss,bb;
int n;
void bfs(int x,int y)
{
queue<qq>xu;
if(a[x][y]==1) { return ;}
ss.x=x;
ss.y=y;
xu.push(ss);
while(xu.empty()!=1)
{
ss=xu.front();
for(int i=0;i<4;i++)
{
if(ss.y+dy[i]>=1&&ss.x+dx[i]>=1&&ss.x+dx[i]<=n&&ss.y+dy[i]<=n){
if(a[ss.x+dx[i]][ss.y+dy[i]]!=1&&(v[ss.x+dx[i]][ss.y+dy[i]]!=1)){
v[ss.x+dx[i]][ss.y+dy[i]]=1;
bb.x=ss.x+dx[i];
bb.y=ss.y+dy[i];
xu.push(bb);
}
else continue;
}
else continue;
}
xu.pop();
}
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
memset(v,0,40);
for(int i=1;i<=n;i++)
{
bfs(1,i);
bfs(i,n);
bfs(i,1);
bfs(n,i);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(v[i][j]==1) a[i][j]=0;
else if(a[i][j]==0) a[i][j]=2;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cout<<a[i][j]<<" ";
if(j==n) cout<<endl;
}
}
P1443 马的遍历
难点在于有8个方向,只需加入一个for循环和8个对应坐标变换的数组即可。
#include<bits/stdc++.h>
using namespace std;
struct qu
{
int x;
int y;
};
int main()
{ qu ss,bb;
int dx[8]={-1,-2,-2,-1,1,2,2,1};
int dy[8]={2,1,-1,-2,2,1,-1,-2};
int n,m,x,y;
cin>>n>>m>>x>>y;
int a[405][405];
int v[405][405];
memset(a,0,sizeof(a));
memset(v,0,sizeof(v));
queue<qu>xu;
ss.x=x;
ss.y=y;
int step=1;
xu.push(ss);
while(xu.empty()!=1)
{
ss=xu.front();
a[x][y]=0;
for(int i=0;i<8;i++)
{
if(ss.y+dy[i]>=1&&ss.x+dx[i]>=1&&ss.x+dx[i]<=n&&ss.y+dy[i]<=m){
if(v[ss.x+dx[i]][ss.y+dy[i]]!=1){
v[ss.x+dx[i]][ss.y+dy[i]]=1;
bb.x=ss.x+dx[i];
bb.y=ss.y+dy[i];
xu.push(bb);
a[ss.x+dx[i]][ss.y+dy[i]]=a[ss.x][ss.y]+1;
}
else continue;
}
else continue;
}
xu.pop();
step++;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{ if(a[i][j]==0&&(i!=x||j!=y)) cout<<"-1"<<" ";
else cout<<a[i][j]<<" ";
if(j==m) cout<<endl;
}
}
P1135 奇怪的电梯
基本的bfs,有两种情况,分别判断是否成立并输入队列。
#include<bits/stdc++.h>
using namespace std;
struct qu
{
int l;
int steps;
};
int k[205];
int c[205];
int n,a,b;
void bfs()
{
qu sta,end;
queue<qu> xu;
sta.l=a;
c[sta.l]=1;
xu.push(sta);
sta.steps=0;
end.steps=0;
while(xu.empty()!=1)
{ sta=xu.front();
xu.pop();
if(sta.l==b) {
cout<<sta.steps;
return;
}
end.l=sta.l+k[sta.l];
end.steps=sta.steps+1;
if(end.l<=n)
{
if(c[end.l]==0)
{
c[end.l]==1;
xu.push(end);
}
}
end.l=sta.l-k[sta.l];
end.steps=sta.steps+1;
if(end.l>=1)
{
if(c[end.l]==0)
{
c[end.l]=1;
xu.push(end);
}
}
}
cout<<-1;
return ;
}
int main()
{
cin>>n>>a>>b;
for(int i=1;i<=n;i++)
{
cin>>k[i];
c[i]=0;
}
bfs();
}