第一个样例
次数 船 方向 左岸 右岸(狼 羊)
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
刚开始用的深搜做的,但是数据量200还是有点大,放弃了(衰,然后用BFS做,过了
很好的一道题,定义一个结构体记录一个岸的羊和狼的数量,然后每动一次,
0号岸和1号岸的数量都会有变化,中间有很多限制,注意!!
ac代码:
#include<stdio.h> #include<string.h> #include<math.h> #include<queue> #include<iostream> #include<algorithm> #define max(a,b) a>b?a:b #define min(a,b) a>b?b:a #define MAXN 220 using namespace std; struct s { int a; int b; int step; int location; }p,d; int n,m,M,bz; int v[2][MAXN][MAXN]; void bfs(int x,int y) { p.a=x; p.b=y; p.step=0; p.location=0;//初始化羊和狼全部在0号岸 queue<s>q; q.push(p); int i,j; while(!q.empty()) { p=q.front(); q.pop(); if(p.a==n&&p.b==m&&p.location==1)//满足条件 { bz=1; printf("%d\n",p.step); return; } d.step=p.step+1;//次数 d.location=p.location==1?0:1;//改变岸 for(i=0;i<=p.a;i++) { for(j=0;j<=p.b;j++) { if(i+j==0)//没有带羊或者狼 continue; if(i+j>M)//带的动物超出上限 continue; if(i<j&&i!=0)//带的羊少于狼 ,注意,此时羊的数量不为0 continue; if(p.a-i<p.b-j&&p.a-i!=0) //带走后剩下的羊数量少于狼 continue; d.a=n-p.a+i;//将要带过去的岸的羊和狼的数量 d.b=m-p.b+j; if(d.a<d.b&&d.a!=0)//如果带过去后羊的数量少于狼 continue; if(v[d.location][d.a][d.b]) //如果此方案使用过 continue; v[d.location][d.a][d.b]=1;//标记此方案使用过 q.push(d); } } } } int main() { while(scanf("%d%d%d",&n,&m,&M)!=EOF) { bz=0; memset(v,0,sizeof(v)); v[0][n][m]=1; bfs(n,m); if(bz==0) printf("-1\n"); } return 0; }