pku1915

本文通过对比链表和数组实现的BFS算法在骑士走法问题上的表现,展示了数据结构选择的重要性。使用数组作为队列的BFS算法不仅通过了测试,而且运行效率更高。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Source Code

Problem: 1915 User: henry11
Memory: 1768K Time: 94MS
Language: G++ Result: Accepted
  • Source Code
  • #include<stdio.h>
    #include<string.h>
    
    struct node
    {
        int a, b;
        int next;
    }; 
    node queue[100000];
    int head, deap, tail;
    int direct[8][2]={-2, 1, -1, 2, 1, 2, 2, 1,
                       2, -1, 1, -2,-1, -2, -2, -1};    
    int chessBoard[301][301];
    int count, length;
    
    void initQueue(int x, int y)
    {
        queue[0].a = x;
        queue[0].b = y;
        queue[0].next = -1;
        head = deap = tail = 0;
    }    
    
    void insertNode(int x, int y)
    {
        tail++;
        queue[tail].a = x;
        queue[tail].b = y;
        chessBoard[x][y] = 1;
        queue[tail].next = -1;
    }    
    
    int BFS(int sa, int sb, int da, int db)
    {
        int n;
        int i, ta = sa, tb = sb;
        initQueue(ta, tb);
        count = 0;
        if(ta == da && tb == db)return count;
        while(head != -1)
        {
            for(i=0; i<8; i++)
            {
                ta = direct[i][0]+queue[head].a;
                tb = direct[i][1]+queue[head].b;
                //printf("firsttest  %d %d/n", ta, tb);
                if(ta>=0 && ta<length && tb>=0 && tb<length)
                {
                    if(ta == da && tb == db)return count+1;
                    if(!chessBoard[ta][tb])insertNode(ta, tb);
                    //printf("secondtest  %d/n", chessBoard[ta][tb]);
                } 
                //scanf("%d", &n);   
            }    
            if(deap == head)
            {
                count++;
                deap = tail;
            }    
            head++;
            //printf("thirdtest  %d/n", count);
        }    
    }    
    
    int main()
    {
        int n, s1, s2, d1, d2;
        scanf("%d", &n);
        while(n--)
        {
            memset(chessBoard, 0, sizeof(chessBoard));
            scanf("%d", &length);
            scanf("%d%d%d%d", &s1, &s2, &d1, &d2);
            printf("%d/n", BFS(s1, s2, d1, d2));
            //scanf("%d", &length);
        }
        return 1;
    }    
应该是很简单的BFS,一开始用链表写超时了 用数组做队列就过了。看来以后对数据结构的选择要慎之又慎。差距很大。
还有他们讲用双向DFS,知道是什么,但从来没写过这个,需要多练练啊,不知道还有没有什么更好的办法。
下面是用链表写的,超时,但结果是对的,也算是一个经验。

#include<stdio.h>
#include<string.h>
#include<time.h>

struct node
{
int a, b;
node *next;
}*queue, *deap, *tail;

int direct[8][2]={-2, 1, -1, 2, 1, 2, 2, 1,
2, -1, 1, -2,-1, -2, -2, -1};

int chessBoard[301][301];
int count, length;

void initQueue(int x, int y)
{
node *p;
p = new node;
p->a = x;
p->b = y;
chessBoard[x][y] = 1;
p->next = NULL;
queue = deap = tail = p;
}

void insertNode(int x, int y)
{
node *p;
p = new node;
p->a = x;
p->b = y;
p->next = NULL;
chessBoard[x][y] = 1;
tail->next = p;
tail = p;
}

void deleteNode()
{
node *p;
p = queue;
queue = p->next;
delete p;
}

int BFS(int sa, int sb, int da, int db)
{
int n;
int ta = sa, tb = sb;
int i, j;
initQueue(ta, tb);
//printf("%d %d/n", queue->a, queue->b);
count = 0;
if(ta == da && tb == db)
{
return count;
}
while(queue)
{
for(i=0; i<8; i++)
{
ta = direct[i][0]+queue->a;
tb = direct[i][1]+queue->b;
//printf("firsttest %d %d %d/n", i, ta, tb);
if(ta>=0 && ta<length && tb>=0 && tb<length)
{
if(ta == da && tb == db)
{
return count+1;
}
//printf("secondtest %d/n", chessBoard[ta][tb]);
if(!chessBoard[ta][tb])
{
insertNode(ta, tb);
}
}
//printf("thirdtest %d %d/n", tail->a, tail->b);
//scanf("%d", &n);
}
if(deap == queue)
{
count++;
deap = tail;
}
deleteNode();
//printf("%d/n", count);
}
}

int main()
{
//int i, j;
double start, complete;
start = (double)clock();
int n, s1, s2, d1, d2;
scanf("%d", &n);
while(n--)
{
memset(chessBoard, 0, sizeof(chessBoard));
scanf("%d", &length);
scanf("%d%d%d%d", &s1, &s2, &d1, &d2);
printf("%d/n", BFS(s1, s2, d1, d2));
//scanf("%d", &length);
}
complete = (double)clock();
printf("%.4fms/n", start-complete);
scanf("%d", &n);
return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值