题目描述:
小a有x只羊和y只狼,现在,他需要通过一座桥。由于桥面很窄,桥每次只允许通过小a和n只动物。小a很爱动物,所以他每次通过桥时都必须有一只动物陪着他,否则他会很寂寞。并且不论是在墙上或者是在桥的两头,一旦羊的数量少于狼的数量,狼就会开始吃羊。为了不让羊被吃掉,又要让所有动物和小a自己都通过桥,小a至少要过桥多少次?
输入:
多组数据,每一组数据包含三个整数x, y, n (0≤ x, y,n ≤ 200)。
输出:
对于每组数据,如果能顺利顺利过桥并且不损失一头羊,则输出需要的最少过桥次数。否则,输出-1。
(据说这又是一个数论题)
按照以往(暂时已知)的套路,数论题总是可以变成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;
}