
Accept: 51 Submit: 129
Time Limit: 3000 mSec Memory Limit : 32768 KB
Problem Description
一天,小明需要把x只羊和y只狼运输到河对面。船可以容纳n只动物和小明。每次小明划船时,都必须至少有一只动物来陪他,不然他会感到厌倦,不安。不论是船上还是岸上,狼的数量如果超过羊,狼就会把羊吃掉。小明需要把所有动物送到对面,且没有羊被吃掉,最少需要多少次他才可以穿过这条河?
Input
有多组数据,每组第一行输入3个整数想x, y, n (0≤ x, y,n ≤ 200)
Output
如果可以把所有动物都送过河,且没有羊死亡,则输出一个整数:最少的次数。 否则输出 -1 .
Sample Input
3 3 233 33 3
Sample Output
11-1
Hint
第一个样例
次数 船 方向 左岸 右岸(狼 羊)
0: 0 0 3 3 0 0
1: 2 0 > 1 3 2 0
2: 1 0 < 2 3 1 0
3: 2 0 > 0 3 3 0
4: 1 0 < 1 3 2 0
5: 0 2 > 1 1 2 2
6: 1 1 < 2 2 1 1
7: 0 2 > 2 0 1 3
8: 1 0 < 3 0 0 3
9: 2 0 > 1 0 2 3
10: 1 0 < 2 0 1 3
11: 2 0 > 0 0 3 3
广搜,节点存入是河两岸羊和狼的数目,当前的步数,以及船的方向。别问我为什么是搜索,估计除了我也不会有人问。。。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
typedef struct node{
int x, y;
int ox, oy;
int step;
int dir;
}Node;
int vis[210][210][2]; //标记状态是否有过
int n;
int bfs(Node s){
queue<Node>q;
q.push(s);
vis[s.x][s.y][s.dir] = 1;
while(!q.empty()){
Node cur = q.front();
q.pop();
if (cur.dir == 1){ //船向右
int x = cur.x;
int y = cur.y;
for (int i = 0; i <= x; i ++){ //遍历可以运走的羊和狼
for (int j = 0; j <= y; j ++){
if((j>i&&i!=0)||(x-i<y-j&&x-i!=0)||i+j>n||i+j==0||(cur.ox+i<cur.oy+j&&cur.ox+i!=0)) //排除不能运走的状况 注意当羊的数量是0时是可以运的
continue;
Node next;
next.x = x - i;
next.y = y - j;
next.ox = cur.ox + i;
next.oy = cur.oy + j;
next.step = cur.step + 1;
next.dir = 0;
if (next.x == 0 && next.y == 0)
return next.step;
if(vis[next.x][next.y][next.dir] == 1)
continue;
else
{
q.push(next);
vis[next.x][next.y][next.dir] = 1;
}
}
}
} else { //船返回的时候,和过去是一样的
int x = cur.ox;
int y = cur.oy;
for (int i = 0; i <= x; i ++){
for(int j = 0; j <= y; j ++){
if((j>i&&i!=0)||(x-i<y-j&&x-i!=0)||i+j>n||i+j==0||(cur.x+i<cur.y+j&&cur.x+i!= 0))
continue;
Node next;
next.ox = x - i;
next.oy = y - j;
next.x = cur.x + i;
next.y = cur.y + j;
next.step = cur.step + 1;
next.dir = 1;
if(vis[next.x][next.y][next.dir] == 1)
continue;
else
{
q.push(next);
vis[next.x][next.y][next.dir] = 1;
}
}
}
}
}
return -1;
}
int main(){
int x, y;
while(scanf("%d%d%d", &x, &y, &n) != EOF){
Node be;
be.x = x;
be.y = y;
be.ox = 0;
be.oy = 0;
be.step = 0;
be.dir = 1; //dir等于1 是向右,就是要运往的方向
printf("%d\n", bfs(be));
}
return 0;
}