2021-05-11

中国象棋中的跳马问题

题目地址: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;
}

调试了近一天,还是太弱了。

你可能感兴趣的:(题解集)