链接:登录—专业IT笔试面试备考平台_牛客网
题目描述:
与普通的dfs的区别就是,它的移动速度是不定的,所以我们不能使用单纯的queue,而可以使用优先队列,因为队列存在的意义,就是要让各个能走的点,以到起点的时间(不是距离,因为速度不定)升序依次处理,那么就应该使用优先队列,来保证队列输出的顺序,是以时间为标准的。
这是第一代代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,k;
struct ty{
int x,y,step;
bool operator<(const ty& s)const{
return step>s.step;
}
};
bool vis[310][310];
ty star,ed;
int dir[][4]={{1,0},{-1,0},{0,1},{0,-1}};
char mas[310][310];
bool inmap(int x,int y){
return x>=0&&y>=0&&x<n&&y<n;
}
void bfs(){
memset(vis,0,sizeof(vis));
priority_queue<ty> q;
q.push(star);
vis[star.x][star.y]=1;
while(!q.empty()){
ty t=q.top();
q.pop();
int x=t.x,y=t.y;
if(mas[x][y]=='X'&&t.step<=k) {cout<<"YES"<<endl<<t.step<<endl;return;}
for(int i=0;i<4;++i){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(inmap(xx,yy)&&!vis[xx][yy]&&mas[xx][yy]!='#'){
if(mas[xx][yy]=='C'){
vis[xx][yy]=1;
q.push({xx,yy,t.step+1});
}
else{
vis[xx][yy]=1;
q.push({xx,yy,t.step+2});
}
}
}
}
cout<<"NO"<<endl;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n>>k;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
cin>>mas[i][j];
if(mas[i][j]=='S') star={i,j};
if(mas[i][j]=='X') ed={i,j};
}
}
bfs();
}
return 0;
}
它wa了。。。
其实还有一个问题我们没有考虑。因为对于每个点,我们其实有两种状态,即:它是我们走过来的,或者它是我们开车过来的,这其实是可以同时存在的,因为我们的速度并非一成不变,我们完全可以先走着经过这里,拿到车之后再开过这里,虽然一个点踩了2次,但之后的路我们却有了更快的速度。当然,如果我们是开着车两次经过同一个点,那肯定还是没有必要的。所以这里的vis数组,我们应该多开一维,记录点的同时,也要记录来时的状态,是开车还是走路,当然也可以直接用速度来记录,后面也方便直接计算时间。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int t,n,k;
struct ty{
int x,y,sp;
long long step;
bool operator<(const ty& s)const{
return step>s.step;
}
};
bool vis[310][310][3];
ty star,ed;
int dir[][4]={{1,0},{-1,0},{0,1},{0,-1}};
char mas[110][110];
bool inmap(int x,int y){
return x>=0&&y>=0&&x<n&&y<n;
}
void bfs(){
memset(vis,0,sizeof(vis));
priority_queue<ty> q;
q.push(star);
vis[star.x][star.y][star.sp]=1;
while(!q.empty()){
ty t=q.top();
q.pop();
int x=t.x,y=t.y,z=t.sp;
if(mas[x][y]=='X'&&t.step<=k) {cout<<"YES"<<endl<<t.step<<endl;return;}
for(int i=0;i<4;++i){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
int zz=z;
int step=t.step;
//if(mas[xx][yy]=='C') zz=1;
if(mas[xx][yy]!='O'&&!vis[xx][yy][zz]&&inmap(xx,yy)){
vis[xx][yy][zz]=1;
step+=z;
if(mas[xx][yy]=='C') zz=1;
q.push({xx,yy,zz,step});
}
}
}
cout<<"NO"<<endl;
return;
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>t;
while(t--){
cin>>n>>k;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
cin>>mas[i][j];
if(mas[i][j]=='S') star={i,j,2,0};
}
}
bfs();
}
return 0;
}
1553

被折叠的 条评论
为什么被折叠?



