P1135 奇怪的电梯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<queue>
using namespace std;
int i,n,a,b,c[202],mar[202];
struct pos{
int step;
int level;
};
pos nex,cur;
int dfs()
{
queue<pos>po;
cur.level=a;
cur.step=0;
mar[a]=1;
po.push(cur);
while(!po.empty())
{
cur=po.front();
if(cur.level==b)
{
cout<<cur.step;
return 0;
}
po.pop();
nex.step=cur.step+1;
nex.level=cur.level+c[cur.level];
if(nex.level<=n)
{
if(mar[nex.level]==0)
{
po.push(nex);
mar[nex.level]=1;
}
}
nex.level=cur.level-c[cur.level];
if(nex.level>=1)
{
if(mar[nex.level]==0)
{
po.push(nex);
mar[nex.level]=1;
}
}
}
cout<<-1;
}
int main()
{
cin>>n>>a>>b;
for(i=1;i<=n;i++)
{
cin>>c[i];
mar[i]=0;
}
dfs();
}
这是dfs例题
P1443 马的遍历 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<queue>
using namespace std;
int n,m,x,y,i,j,mar[402][402],u,v,res[402][402];
int a[8]={-2,-1,1,2,2,1,-1,-2};
int b[8]={-1,-2,-2,-1,1,2,2,1};
struct man{
int x;
int y;
int step;
};
int check(man k)
{
if(k.x==u&&k.y==v) return 1;
return 0;
}
int check1(man k)
{
if(k.x<=n&&k.y<=m&&mar[k.x][k.y]==0&&k.x>=1&&k.y>=1) return 1;
return 0;
}
int dfs()
{
queue<man>qu;
man cur,nex;
cur.x=x;
cur.y=y;
cur.step=1;
mar[x][y]=1;
res[x][y]=0;
qu.push(cur);
while(!qu.empty())
{
cur=qu.front();
qu.pop();
for(i=0;i<8;i++)
{
nex.x=cur.x+a[i];
nex.y=cur.y+b[i];
nex.step=cur.step+1;
if(check1(nex))
{
mar[nex.x][nex.y]=1;
res[nex.x][nex.y]=cur.step;
qu.push(nex);
}
}
}
}
int main()
{
cin>>n>>m>>x>>y;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
mar[i][j]=0;
res[i][j]=-1;
}
}
dfs();
for(u=1;u<=n;u++)
{
for(v=1;v<=m;v++)
{
cout<<res[u][v]<<" ";
}
cout<<endl;
}
}
这跟上一道题类似;
P3958 [NOIP2017 提高组] 奶酪 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<queue>
using namespace std;
long long t,n,h,r,i,j,mar[1003];
struct man
{
long long x;
long long y;
long long z;
long long max;
long long min;
};
man a[1003],cur,nex;
int check()
{
if(4*r*r>=(cur.x-a[i].x)*(cur.x-a[i].x)+(cur.y-a[i].y)*(cur.y-a[i].y)+(cur.z-a[i].z)*(cur.z-a[i].z))
{
if(mar[i]==0)
return 1;
}
return 0;
}
int dfs()
{
queue<man>qu;
for(i=1;i<=n;i++)
{
if(a[i].min<=0)
{
qu.push(a[i]);
mar[i]=1;
}
}
cur=qu.front();
while(!qu.empty())
{
cur=qu.front();
qu.pop();
if(cur.max>=h)
{
cout<<"Yes"<<endl;
return 1;
}
for(i=1;i<=n;i++)
{
if(check())
{
nex=a[i];
mar[i]=1;
qu.push(nex);
}
}
}
cout<<"No"<<endl;
}
int main()
{
cin>>t;
for(j=1;j<=t;j++)
{
cin>>n>>h>>r;
for(i=1;i<=n;i++)
{
cin>>a[i].x;
cin>>a[i].y;
cin>>a[i].z;
a[i].max=a[i].z+r;
a[i].min=a[i].z-r;
mar[i]=0;
}
dfs();
}
}
这道题一开始先选择了把所有跟地面相切的球放入队列。我一开始写的时候没有这么想,我想的是按照输入的顺序,第一个球心坐标放到队列里,再把所有其他的没有被选中过的坐标也放进去,每次放进队列的操作使当前被选中的两个坐标所表示的球的最上面的点与最下面的点的大小更新,并保存都到这两个坐标里,也就是收如果有几个球连在一起,那么它们所表示的最上面点的最大值就是这几个球最上面的点的最大值,最小值同理。然而应该注意的是,有可能一堆球连接在一起,另外一堆球也连接在一起,但是这两堆球没有任何通道联系,所以没办法就让上面的操作重复n次。已经被考虑过的两个坐标组被标记,在重复操作的过程中可以跳过。但是这个想法错了。
P1162 填涂颜色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<iostream>
#include<queue>
using namespace std;
int n,i,j,mar[32][32],d;
struct man
{
int i;
int j;
int r;
};
man a[32][32];
man cur;
man nex;
queue<man>qu;
void check()
{
if(!nex.r&&!mar[nex.i][nex.j]&&nex.i<=n&&nex.j<=n&&nex.i>=1&&nex.j>=1)
{
qu.push(nex);
mar[nex.i][nex.j]=1;
}
}
int dfs()
{
d=1;
while(d<=4*n-4)
{
while(!qu.empty()) qu.pop();
if(d<=n)
{
i=1;
j=d;
}
if(d<=2*n-1&&d>n)
{
i=d-n+1;
j=n;
}
if(d<=3*n-2&&d>2*n-1)
{
i=n;
j=3*n-1-d;
}
if(d<=4*n-4&&d>3*n-2)
{
i=4*n-2-d;
j=1;
}
if(a[i][j].r==1)
{
d++;
continue;
}
queue<man>qu;
qu.push(a[i][j]);
mar[i][j]=1;
while(!qu.empty())
{
cur=qu.front();
qu.pop();
nex.i=cur.i+1;
nex.j=cur.j;
nex.r=a[nex.i][nex.j].r;
if(!nex.r&&!mar[nex.i][nex.j]&&nex.i<=n&&nex.j<=n&&nex.i>=1&&nex.j>=1)
{
qu.push(nex);
mar[nex.i][nex.j]=1;
}
nex.i=cur.i;
nex.j=cur.j+1;
nex.r=a[nex.i][nex.j].r;
if(!nex.r&&!mar[nex.i][nex.j]&&nex.i<=n&&nex.j<=n&&nex.i>=1&&nex.j>=1)
{
qu.push(nex);
mar[nex.i][nex.j]=1;
}
nex.i=cur.i-1;
nex.j=cur.j;
nex.r=a[nex.i][nex.j].r;
if(!nex.r&&!mar[nex.i][nex.j]&&nex.i<=n&&nex.j<=n&&nex.i>=1&&nex.j>=1)
{
qu.push(nex);
mar[nex.i][nex.j]=1;
}
nex.i=cur.i;
nex.j=cur.j-1;
nex.r=a[nex.i][nex.j].r;
if(!nex.r&&!mar[nex.i][nex.j]&&nex.i<=n&&nex.j<=n&&nex.i>=1&&nex.j>=1)
{
qu.push(nex);
mar[nex.i][nex.j]=1;
}
}
d++;
}
}
int main()
{
cin>>n;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>a[i][j].r;
a[i][j].i=i;
a[i][j].j=j;
mar[i][j]=0;
}
}
dfs();
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(mar[i][j]==1&&a[i][j].r==0) cout<<0<<' ';
if(a[i][j].r==1) cout<<1<<' ';
if(mar[i][j]==0&&a[i][j].r==0) cout<<2<<' ';
}
cout<<endl;
}
}
这是一种写法。
有一个卡了我很久的地方是那个check函数,这个代码并没有调用它,一调用就全错了,不调用他全对,没想到这个地方会这么(恼