#P3245. 狼羊过河(200分)
-
1000ms
Tried: 106
Accepted: 27
Difficulty: 5
所属公司 :
华为od
狼羊过河(200分)
题面描述
在一个河岸上,有一定数量的羊和狼,以及一个农夫。农夫需要将所有的羊和狼安全地运输到对岸,但有几个重要的限制条件:
- 如果羊的数量小于狼的数量,狼会攻击羊。因此,在任何情况下,岸上的羊的数量必须大于岸上的狼的数量,才能保证羊的安全。
- 农夫有一只船,船的容量有限,不能超过这个容量进行运输。
- 在运输的过程中,农夫始终在船上,因此船上可以装载任何数量的动物,只要不超过船的容量。
要求计算在不损失羊的情况下,将所有羊和狼运输到对岸所需的最小次数。如果无法满足条件,则返回 0。
思路
解决该问题的核心思路是使用暴力枚举法,结合深度优先搜索(DFS)来尝试所有可能的运输组合。具体步骤如下:
-
递归函数定义:
- 定义一个递归函数
dfs,参数包括当前岸上的羊和狼的数量、船的容量、对岸的羊和狼的数量以及当前的运输次数。
- 定义一个递归函数
-
结束条件:
- 如果当前岸上的羊和狼都运输完成,则更新最小次数的记录。
- 如果当前岸上的羊和狼数量不超过船的容量,直接更新最小次数的记录。
-
运输组合选择:
- 使用两个嵌套循环,枚举船上运输的羊和狼的数量。
- 检查运输后的岸上羊和狼的数量是否符合安全条件:
- 本岸羊的数量必须大于本岸狼的数量。
- 对岸羊的数量必须大于对岸狼的数量。
-
递归调用:
- 在满足安全条件的情况下,进行下一轮运输的递归调用。
-
结果输出:
- 如果找到有效的运输方案,返回最小运输次数;否则返回 0。
cpp
#include <bits/stdc++.h>
using namespace std;
int ans = INT_MAX;
// 深度优先搜索函数
void dfs(int sheep, int wolf, int boat, int oppo_sheep, int oppo_wolf, int count) {
// 如果所有羊和狼都已运输完成
if (sheep == 0 && wolf == 0) {
ans = min(ans, count);
return;
}
// 如果当前岸上的羊和狼数量不超过船的容量
if (sheep + wolf <= boat) {
ans = min(ans, count + 1);
return;
}
// 选取船上运送的羊的数量
for (int i = 0; i <= min(boat, sheep); i++) {
// 选取船上运送的狼的数量
for (int j = 0; j <= min(boat, wolf); j++) {
// 如果船上不运输任何动物,跳过
if (i + j == 0) continue;
// 如果船上动物数量超过船的容量,跳出循环
if (i + j > boat) break;
// 检查本岸的羊和狼的数量
if (sheep - i <= wolf - j && sheep - i != 0) continue;
// 检查对岸的羊和狼的数量
if (oppo_sheep + i <= oppo_wolf + j && oppo_sheep + i != 0) break;
// 检查对岸的情况,如果对岸没有羊且狼超过船载量
if (oppo_sheep + i == 0 && oppo_wolf + j >= boat) break;
// 进行下一次运输
dfs(sheep - i, wolf - j, boat, oppo_sheep + i, oppo_wolf + j, count + 1);
}
}
}
// 解决方案
int solution(int sheep, int wolf, int boat) {
dfs(sheep, wolf, boat, 0, 0, 0);
// 如果没有找到合适的运输方案
return (ans == INT_MAX) ? 0 : ans;
}
int main() {
int m, n, x;
cin >> m >> n >> x;
cout << solution(m, n, x) << endl;
return 0;
}
python
import sys
ans = float('inf') # 初始化答案为正无穷
# 深度优先搜索函数
def dfs(sheep, wolf, boat, oppo_sheep, oppo_wolf, count):
global ans
# 如果所有羊和狼都已运输完成
if sheep == 0 and wolf == 0:
ans = min(ans, count)
return
# 如果当前岸上的羊和狼数量不超过船的容量
if sheep + wolf <= boat:
ans = min(ans, count + 1)
return
# 选取船上运送的羊的数量
for i in range(min(boat, sheep) + 1):
# 选取船上运送的狼的数量
for j in range(min(boat, wolf) + 1):
# 如果船上不运输任何动物,跳过
if i + j == 0:
continue
# 如果船上动物数量超过船的容量,跳出循环
if i + j > boat:
break
# 检查本岸的羊和狼的数量
if sheep - i <= wolf - j and sheep - i != 0:
continue
# 检查对岸的羊和狼的数量
if oppo_sheep + i <= oppo_wolf + j and oppo_sheep + i != 0:
break
# 检查对岸的情况,如果对岸没有羊且狼超过船载量
if oppo_sheep + i == 0 and oppo_wolf + j >= boat:
break
# 进行下一次运输
dfs(sheep - i, wolf - j, boat, oppo_sheep + i, oppo_wolf + j, count + 1)
# 解决方案
def solution(sheep, wolf, boat):
dfs(sheep, wolf, boat, 0, 0, 0)
# 如果没有找到合适的运输方案
return 0 if ans == float('inf') else ans
# 主函数
if __name__ == "__main__":
m, n, x = map(int, input().split())
print(solution(m, n, x))
java
import java.util.Scanner;
public class Main {
static int ans = Integer.MAX_VALUE; // 初始化答案为最大整数
// 深度优先搜索函数
public static void dfs(int sheep, int wolf, int boat, int oppoSheep, int oppoWolf, int count) {
// 如果所有羊和狼都已运输完成
if (sheep == 0 && wolf == 0) {
ans = Math.min(ans, count);
return;
}
// 如果当前岸上的羊和狼数量不超过船的容量
if (sheep + wolf <= boat) {
ans = Math.min(ans, count + 1);
return;
}
// 选取船上运送的羊的数量
for (int i = 0; i <= Math.min(boat, sheep); i++) {
// 选取船上运送的狼的数量
for (int j = 0; j <= Math.min(boat, wolf); j++) {
// 如果船上不运输任何动物,跳过
if (i + j == 0) continue;
// 如果船上动物数量超过船的容量,跳出循环
if (i + j > boat) break;
// 检查本岸的羊和狼的数量
if (sheep - i <= wolf - j && sheep - i != 0) continue;
// 检查对岸的羊和狼的数量
if (oppoSheep + i <= oppoWolf + j && oppoSheep + i != 0) break;
// 检查对岸的情况,如果对岸没有羊且狼超过船载量
if (oppoSheep + i == 0 && oppoWolf + j >= boat) break;
// 进行下一次运输
dfs(sheep - i, wolf - j, boat, oppoSheep + i, oppoWolf + j, count + 1);
}
}
}
// 解决方案
public static int solution(int sheep, int wolf, int boat) {
dfs(sheep, wolf, boat, 0, 0, 0);
// 如果没有找到合适的运输方案
return (ans == Integer.MAX_VALUE) ? 0 : ans;
}
// 主函数
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt(); // 羊的数量
int n = scanner.nextInt(); // 狼的数量
int x = scanner.nextInt(); // 船的容量
System.out.println(solution(m, n, x)); // 输出最小运输次数
scanner.close();
}
}
题目内容
羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。
要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。
只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。
备注:农夫在或农夫离开后羊的数量大于狼的数量时狼不会攻击羊。
输入描述
第一行输入为 M,N,X, 分别代表羊的数量,狼的数量,小船的容量。
M<=10,N<=10,X<=10
输出描述
输出不损失羊情况下将全部羊和狼运到对岸需要的最小次数(若无法满足条件则输出 0)。
样例1
输入
5 3 3
输出
3
说明
第一次运2只狼
第二次运3只羊
第三次运2只羊和1只狼
样例2
输入
5 4 1
输出
0
说明
如果找不到不损失羊的运送方案,输出0