网教30. 过桥

题目描述:

小a有x只羊和y只狼,现在,他需要通过一座桥。由于桥面很窄,桥每次只允许通过小a和n只动物。小a很爱动物,所以他每次通过桥时都必须有一只动物陪着他,否则他会很寂寞。并且不论是在墙上或者是在桥的两头,一旦羊的数量少于狼的数量,狼就会开始吃羊。为了不让羊被吃掉,又要让所有动物和小a自己都通过桥,小a至少要过桥多少次?

输入:

多组数据,每一组数据包含三个整数x, y, n (0≤ x, y,n ≤ 200)。

输出:

对于每组数据,如果能顺利顺利过桥并且不损失一头羊,则输出需要的最少过桥次数。否则,输出-1。

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. 2↵
  2. 3 3 2↵
  3. 33 33 3↵
以文本方式显示
  1. 11↵
  2. -1↵
1秒 64M 0
题解:
(据说这又是一个数论题)
按照以往(暂时已知)的套路,数论题总是可以变成BFS,所以我就用BFS试了试……
开两个结构数组,分别存在河的一边和另一边时候的羊数、狼数、走的次数。然后一个vis[200][200][2]三维分别存羊数、狼数、河的哪边。每次操作的时候是最少带一只动物,最多带n只,在河的两边和桥上都不能出现狼数>羊数的情况。对于符合题意的情况,就加入队列,并标记vis。一直BFS搜索,只到所有的动物都到了对岸,或者front<rear,结束,输出结果。
思路不难,一点一点写就能写出来。代码量(至少是我的代码量)较大,所以写着需要细心。细节的地方容易出千奇百怪的错,所以还是要注意细节。
AC代码:
#include<stdio.h>  
#include<string.h>  
struct node  
{  
    int x, y, index;  
}a[400005], b[400005];  
int vis[205][205][2];  
int x, y, n;  
  
int bfs()  
{  
    int front = 0, rear = 1;  
    a[front].x = x;  
    a[front].y = y;  
    a[front].index = 0;  
    b[front].x = 0;  
    b[front].y = 0;  
    b[front].index = 0;  
    vis[x][y][0] = 1;  
    vis[0][0][1] = 1;  
    int k = 0, flag = 0;  
    while (front < rear)  
    {  
        if (b[front].x == x&&b[front].y == y)  
        {  
            flag = 1;  
            return b[front].index;  
        }  
        if (a[front].index % 2 == 0)  
            k = 0;  
        else  
            k = 1;  
        if (k == 0)  
        {  
            for (int i = 0; i <= n; i++)  
            for (int j = 0; j <= n - i; j++)//i:带上几只羊,j:带上几只狼  
            {  
                if (i + j == 0 || (i != 0 && i < j))  
                    continue;  
                int x1 = a[front].x - i;  
                int x2 = b[front].x + i;  
                int y1 = a[front].y - j;  
                int y2 = b[front].y + j;  
                if (x1 > x || x2 > x || y1 > y || y2 > y || x1 < 0 || y1 < 0)  
                    continue;  
                if (vis[x1][y1][0] == 0 && (x1 >= y1 || x1 == 0) && (x2 >= y2 || x2 == 0))  
                {  
                    vis[x1][y1][0] = 1;  
                    a[rear].x = x1;  
                    a[rear].y = y1;  
                    a[rear].index = a[front].index + 1;  
                    b[rear].x = x2;  
                    b[rear].y = y2;  
                    b[rear].index = b[front].index + 1;  
                    rear++;  
                }  
            }  
        }  
        else  
        {  
            for (int i = 0; i <= n; i++)  
            for (int j = 0; j <= n - i; j++)  
            {  
                if (i + j == 0 || (i != 0 && i < j))  
                    continue;  
                int x1 = a[front].x + i;  
                int x2 = b[front].x - i;  
                int y1 = a[front].y + j;  
                int y2 = b[front].y - j;  
                if (x1 > x || x2 > x || y1 > y || y2 > y || x2 < 0 || y2 < 0)  
                    continue;  
                if (vis[x2][y2][1] == 0 && (x1 >= y1 || x1 == 0) && (x2 >= y2 || x2 == 0))  
                {  
                    vis[x2][y2][1] = 1;  
                    a[rear].x = x1;  
                    a[rear].y = y1;  
                    a[rear].index = a[front].index + 1;  
                    b[rear].x = x2;  
                    b[rear].y = y2;  
                    b[rear].index = b[front].index + 1;  
                    rear++;  
                }  
            }  
        }  
        front++;  
    }  
    return -1;  
}  
int main()  
{  
    int t;  
    scanf("%d", &t);  
    while (t--)  
    {  
        memset(vis, 0, sizeof(vis));  
  
        scanf("%d%d%d", &x, &y, &n);  
        if (x < y || n < 1)  
            printf("-1\n");  
        else  
        {  
            int ans = bfs();  
            printf("%d\n",ans);  
        }  
    }  
    return 0;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值