题目地址:http://acm.ticknet.hnust.cn/problem.php?cid=2286&pid=4
题目大意:在一个有障碍物(限制马的行动)的棋盘中,给出马的起始位置和最终位置现要求出马是否能到达最终位置,若能到达最终位置就输出最少的步数。
思路:使用bfs即可。贴出两个错误代码一个正确代码。
错误1:
#include
#include
#include
#include
#include
#include
using namespace std;
const int inf=0x3f3f3f3f;
int vit[105][105],p,q,c,d;
int dx[10]= {-2,-1,1,2,2,1,-1,-2};
int dy[10]= {1,2,2,1,-1,-2,-2,-1};
typedef struct dote
{
int a,b,cnt;
} dote;
queue<dote>s;
void bfs(dote k)
{
s.push(k);
vit[k.a][k.b]=2;
while(!s.empty())
{
dote t,x=s.front();
s.pop();
for(int i=0; i<8; i++)
{
if(x.a+dx[i]<1||x.a+dx[i]>p||x.b+dy[i]<1||x.b+dy[i]>q)
continue;
if(vit[x.a+dx[i]][x.b+dy[i]]==1||vit[x.a+dx[i]][x.b+dy[i]]==2)
continue;
if(vit[x.a+dx[i]/2][x.b+dy[i]/2]==1)
continue;
t.a=x.a+dx[i],t.b=x.b+dy[i],t.cnt=x.cnt+1;
if(vit[x.a+dx[i]][x.b+dy[i]]==0)
{
t.a=x.a+dx[i],t.b=x.b+dy[i],t.cnt=x.cnt+1;
s.push(t);
vit[t.a][t.b]=2;
}
if(t.a==c&&t.b==d)
{
vit[c][d]=t.cnt;//这里vit[c][d]等于inf而inf为不可更改的值
return;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int m,x,y;
dote k;
k.cnt=0;
//while(!s.empty()) s.pop();
memset(vit,0,sizeof(vit));
scanf("%d%d%d%d%d%d%d",&p,&q,&k.a,&k.b,&c,&d,&m);
vit[c][d]=inf;
for(int i=0; i<m; i++)
{
scanf("%d%d",&x,&y);
vit[x][y]=1;
}
bfs(k);
if(vit[c][d]==inf)
printf("can not reach!\n");
else
printf("%d\n",vit[x][y]);
}
return 0;
}
错误2:
#include
#include
#include
#include
#include
#include
using namespace std;
int vit[105][105],p,q,c,d;
int dx[10]= {-2,-1,1,2,2,1,-1,-2};
int dy[10]= {1,2,2,1,-1,-2,-2,-1};
typedef struct dote
{
int a,b,cnt;
} dote;
void bfs(dote k)
{
queue<dote>s;
s.push(k);
vit[k.a][k.b]=2;
while(!s.empty())
{
dote t,x=s.front();
s.pop();
if(x.a==c&&x.b==d)
{
vit[c][d]=x.cnt;
return;
}
for (int i = 0; i < 8; i++)
{
t.a = x.a + dx[i], t.b = x.b + dy[i], t.cnt = x.cnt + 1;
if (t.a< 1 || t.a> p || t.b< 1 || t.b > q)
continue;
if (vit[t.a ][t.b ] == 1 || vit[t.a][t.b ] == 2)
continue;
if (vit[x.a + dx[i] / 2][x.b + dy[i] / 2] == 1)
continue;
s.push(t);
vit[t.a][t.b]=2;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int m,x,y;
dote k;
k.cnt=0;
memset(vit,0,sizeof(vit));
scanf("%d%d%d%d%d%d%d",&p,&q,&k.a,&k.b,&c,&d,&m);
for(int i=0; i<m; i++)
{
scanf("%d%d",&x,&y);
vit[x][y]=1;
}
if(k.a==c&&k.b==d)
{
cout<<0<<endl;
continue;
}
vit[c][d]=-1;//不能设为-1因为有可能该位置原本有障碍物
bfs(k);
if(vit[c][d]==-1)
printf("can not reach!\n");
else
printf("%d\n",vit[c][d]);
}
return 0;
}
正确的:
#include
#include
#include
#include
#include
#include
using namespace std;
int vit[105][105],p,q,c,d,ans;
int dx[10]= {-2,-1,1,2,2,1,-1,-2};
int dy[10]= {1,2,2,1,-1,-2,-2,-1};
typedef struct dote
{
int a,b,cnt;
} dote;
void bfs(dote k)
{
queue<dote>s;
s.push(k);
vit[k.a][k.b]=2;
while(!s.empty())
{
dote t,x=s.front();
s.pop();
if(x.a==c&&x.b==d)
{
ans=x.cnt;
return;
}
for (int i = 0; i < 8; i++)
{
t.a = x.a + dx[i], t.b = x.b + dy[i], t.cnt = x.cnt + 1;
if (t.a<1||t.a>p||t.b<1||t.b>q)
continue;
if (vit[t.a][t.b]==1||vit[t.a][t.b]== 2)
continue;
if (vit[x.a+dx[i]/2][x.b+dy[i]/2]==1)
continue;
s.push(t);
vit[t.a][t.b]=2;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int m,x,y;
dote k;
k.cnt=0;
ans=-1;
memset(vit,0,sizeof(vit));
scanf("%d%d%d%d%d%d%d",&p,&q,&k.a,&k.b,&c,&d,&m);
for(int i=0; i<m; i++)
{
scanf("%d%d",&x,&y);
vit[x][y]=1;
}
bfs(k);
if(ans==-1)
printf("can not reach!\n");
else
printf("%d\n",ans);
}
return 0;
}
调试了近一天,还是太弱了。