题目描述
羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。
要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。
只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。
备注:农夫在或农夫离开后羊的数量大于狼的数量时狼不会攻击羊。
输入描述
第一行输入为M,N,X, 分别代表羊的数量,狼的数量,小船的容量。
输出描述
输出不损失羊情况下将全部羊和狼运到对岸需要的最小次数(若无法满足条件则输出0)。
用例1
输入
5 3 3
输出
3
说明
第一次运2只狼
第二次运3只羊
第三次运2只羊和1只狼
用例2
输入
5 4 1
输出
0
说明
如果找不到不损失羊的运送方案,输出0
思路:这题我的思路是,定义一个过河函数,如下
在右边羊大于右边狼,或者右边没有羊的前提下:
正常的过河羊需要大于狼才可以,这种情况下,按照左边羊>狼+1,就送一只羊
左边羊=狼+1,而船余量>1,一只狼一只羊的送
左边羊=狼+1,而船余量=1,判断对岸羊>狼+1?,是就送一只狼
左侧无狼,就全送羊
这样保证了左侧羊>狼,右侧也尽可能让羊大于狼
但是这样还有特例
1.比如船可以一波把羊送走,狼<船余量*2-1,这样可以先送一船狼过去,然后左边羊>=狼+1,
再把剩余狼送过去,最后送羊,这种属于特例也要考虑进去
2.俩边都没有羊,只有狼,就只送狼就行了
函数如下:
public static int[] forriver(int sheep, int wolf, int boat,int sheep2, int wolf2){
int[] arr = new int[5];//定义一个数组返回参数
int boat2=boat;//定义一个船余量作为比较
int jug=0;//定义一个运船成功与否判断
while(boat2!=0&&jug==0){//
jug=1;//开始定义判断为1,如果以下条件都没有达成,jug依然为1,跳出循环
if(sheep>wolf+1&&(sheep2>wolf2||wolf2==0)){sheep--;boat2--;sheep2++;jug=0;}//羊大于狼+1,则运一只羊
else if(sheep==wolf+1){//如果羊不大于狼+1,且还有狼和羊,对岸羊比狼多,则一只狼+一只羊的送
if(boat2>1&&wolf!=0&&sheep!=0&&sheep2>wolf2){wolf--;sheep--;wolf2++;sheep2++;boat2-=2;jug=0;}
//如果船余量没有俩个了,看看对岸的羊是否大于狼+1,并且还有狼,是就送一只狼
if(boat2==1&&sheep2>wolf2+1&&wolf!=0){wolf--;wolf2++;boat2-=1;jug=0;}
}//如果狼为0,就能送多少羊送多少羊
if(wolf==0){while(boat2!=0&&sheep!=0){boat2--;sheep--;sheep2++;jug=0;}}
if(sheep+wolf<boat2){sheep2+=sheep;wolf2+=wolf;sheep=0;wolf=0;boat2=0;}
//如果狼和羊数量都少于余量,直接全部送走
//特例,羊可以一波送走
if(sheep2==0&&sheep<=boat&&wolf+wolf2<=boat*2-1&&wolf!=0){
if(wolf2==0&&wolf>=boat2){wolf-=boat2;wolf2+=boat2;boat2=0;}
else if(wolf2==boat2){wolf2+=wolf;wolf=0;boat2=0;}
else if(wolf2==0){wolf2=wolf;boat2=0;wolf=0;}
}//特例,没有羊只有狼
if(sheep==0&&sheep2==0){while(boat2!=0&&wolf!=0){boat2--;wolf--;wolf2++;jug=0;}}
}
if(boat2==boat)arr[0]=1;//如果余量没有减少,则运送失败,数组第一个数改为1,意思是失败了
else {arr[1]=sheep;arr[2]=wolf;arr[3]=sheep2;arr[4]=wolf2;}
System.out.println("羊 狼 对岸羊 对岸狼:");
System.out.println(sheep+" "+wolf+" "+sheep2+" "+wolf2);
return arr;
}
完整代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
while(1==1) {
System.out.println("输入羊数目 狼数目 船容量");
int sheep = scanner.nextInt();//羊数目
int wolf = scanner.nextInt();//狼数目
int boat = scanner.nextInt();//船容量
int sum = 0;//运送次数
int sheep2 = 0;//对岸羊数目
int wolf2 = 0;//对岸狼数目
int[] array = new int[5];//定义一个数组接收函数返回的羊狼数目,以及是否达成运送条件
while (sheep + wolf != 0) {
array = forriver(sheep, wolf, boat, sheep2, wolf2);
if (array[0] == 1) {
break;
} else {
sheep = array[1];
wolf = array[2];
sheep2 = array[3];
wolf2 = array[4];
sum++;
}
}
System.out.print("需要的次数为:");
System.out.println(sum);
}
}
public static int[] forriver(int sheep, int wolf, int boat,int sheep2, int wolf2){
int[] arr = new int[5];//定义一个数组返回参数
int boat2=boat;//定义一个船余量作为比较
int jug=0;//定义一个运船成功与否判断
while(boat2!=0&&jug==0){//
jug=1;//开始定义判断为1,如果以下条件都没有达成,jug依然为1,跳出循环
if(sheep>wolf+1&&(sheep2>wolf2||wolf2==0)){sheep--;boat2--;sheep2++;jug=0;}//羊大于狼+1,则运一只羊
else if(sheep==wolf+1){//如果羊不大于狼+1,且还有狼和羊,对岸羊比狼多,则一只狼+一只羊的送
if(boat2>1&&wolf!=0&&sheep!=0&&sheep2>wolf2){wolf--;sheep--;wolf2++;sheep2++;boat2-=2;jug=0;}
//如果船余量没有俩个了,看看对岸的羊是否大于狼+1,并且还有狼,是就送一只狼
if(boat2==1&&sheep2>wolf2+1&&wolf!=0){wolf--;wolf2++;boat2-=1;jug=0;}
}//如果狼为0,就能送多少羊送多少羊
if(wolf==0){while(boat2!=0&&sheep!=0){boat2--;sheep--;sheep2++;jug=0;}}
if(sheep+wolf<boat2){sheep2+=sheep;wolf2+=wolf;sheep=0;wolf=0;boat2=0;}
//如果狼和羊数量都少于余量,直接全部送走
//特例,羊可以一波送走
if(sheep2==0&&sheep<=boat&&wolf+wolf2<=boat*2-1&&wolf!=0){
if(wolf2==0&&wolf>=boat2){wolf-=boat2;wolf2+=boat2;boat2=0;}
else if(wolf2==boat2){wolf2+=wolf;wolf=0;boat2=0;}
else if(wolf2==0){wolf2=wolf;boat2=0;wolf=0;}
}//特例,没有羊只有狼
if(sheep==0&&sheep2==0){while(boat2!=0&&wolf!=0){boat2--;wolf--;wolf2++;jug=0;}}
}
if(boat2==boat)arr[0]=1;//如果余量没有减少,则运送失败,数组第一个数改为1,意思是失败了
else {arr[1]=sheep;arr[2]=wolf;arr[3]=sheep2;arr[4]=wolf2;}
System.out.println("羊 狼 对岸羊 对岸狼:");
System.out.println(sheep+" "+wolf+" "+sheep2+" "+wolf2);
return arr;
}
}
测试:
输入羊数目 狼数目 船容量
5 3 3
羊 狼 对岸羊 对岸狼:
3 2 2 1
羊 狼 对岸羊 对岸狼:
2 1 3 2
羊 狼 对岸羊 对岸狼:
0 0 5 3
需要的次数为:3
输入羊数目 狼数目 船容量
5 4 1
羊 狼 对岸羊 对岸狼:
5 4 0 0
需要的次数为:0
输入羊数目 狼数目 船容量
5 9 5
羊 狼 对岸羊 对岸狼:
5 4 0 5
羊 狼 对岸羊 对岸狼:
5 0 0 9
羊 狼 对岸羊 对岸狼:
0 0 5 9
需要的次数为:3
输入羊数目 狼数目 船容量
5 6 5
羊 狼 对岸羊 对岸狼:
5 1 0 5
羊 狼 对岸羊 对岸狼:
5 0 0 6
羊 狼 对岸羊 对岸狼:
0 0 5 6
需要的次数为:3
输入羊数目 狼数目 船容量
0 12 5
羊 狼 对岸羊 对岸狼:
0 7 0 5
羊 狼 对岸羊 对岸狼:
0 2 0 10
羊 狼 对岸羊 对岸狼:
0 0 0 12
需要的次数为:3
输入羊数目 狼数目 船容量
12 0 5
羊 狼 对岸羊 对岸狼:
7 0 5 0
羊 狼 对岸羊 对岸狼:
2 0 10 0
羊 狼 对岸羊 对岸狼:
0 0 12 0
需要的次数为:3
输入羊数目 狼数目 船容量
999 997 123
羊 狼 对岸羊 对岸狼:
937 936 62 61
羊 狼 对岸羊 对岸狼:
876 875 123 122
羊 狼 对岸羊 对岸狼:
815 814 184 183
羊 狼 对岸羊 对岸狼:
754 753 245 244
羊 狼 对岸羊 对岸狼:
693 692 306 305
羊 狼 对岸羊 对岸狼:
632 631 367 366
羊 狼 对岸羊 对岸狼:
571 570 428 427
羊 狼 对岸羊 对岸狼:
510 509 489 488
羊 狼 对岸羊 对岸狼:
449 448 550 549
羊 狼 对岸羊 对岸狼:
388 387 611 610
羊 狼 对岸羊 对岸狼:
327 326 672 671
羊 狼 对岸羊 对岸狼:
266 265 733 732
羊 狼 对岸羊 对岸狼:
205 204 794 793
羊 狼 对岸羊 对岸狼:
144 143 855 854
羊 狼 对岸羊 对岸狼:
83 82 916 915
羊 狼 对岸羊 对岸狼:
22 21 977 976
羊 狼 对岸羊 对岸狼:
0 0 999 997
需要的次数为:17
输入羊数目 狼数目 船容量