蓝桥杯2020省赛真题 作物杂交问题
作者:互联网
作物杂交
题目描述
作物杂交是作物栽培中重要的一步。已知有 N 种作物 (编号 1至 N ),第 i 种作物从播种到成熟的时间为 Ti 。作物之间两两可以进行杂交,杂交时间取两种中时间较长的一方。如作物 A 种植时间为 5 天,作物 B 种植时间为 7 天,则 A B 杂交花费的时间为 7 天。作物杂交会产生固定的作物,新产生的作物仍然属于 N 种作物中的一种。
初始时,拥有其中 M 种作物的种子 (数量无限,可以支持多次杂交)。同时可以进行多个杂交过程。求问对于给定的目标种子,最少需要多少天能够得到。
如存在 4 种作物 ABCD,各自的成熟时间为 5 天、7 天、3 天、8 天。初始拥有 AB 两种作物的种子,目标种子为 D,已知杂交情况为 A × B → C,A × C → D。
则最短的杂交过程为:
第 1 天到第 7 天 (作物 B 的时间),A × B → C。
第 8 天到第 12 天 (作物 A 的时间),A × C → D。
花费 12 天得到作物 D 的种子。
C++
#include <iostream>
using namespace std;
const int MAXN = 2000+5;
int n, m, k, goal;
int t[MAXN];
bool have_k[MAXN];
int zajiao[MAXN][MAXN];
int limit_time;
struct father {
int num;
int u[MAXN];
int v[MAXN];
int limtime;
}fa[MAXN];
void swap(int& a, int& b) {
int tep = a; a = b; b = tep;
}
void input() {
//N,M,K,T,
//N 表示作物种类总数 (编号 11 至 N),
//M 表示初始拥有的作物种子类型数量,
//K 表示可以杂交的方案数,T 表示目标种子的编号。
cin >> n >> m >> k >> goal;
for (int i = 1; i <= n; i++)
cin >> t[i];
for (int i = 1; i <= m; i++) {
int z;
cin >> z;
have_k[z] = true;
}
for (int i = 1; i <= k; i++) {
int u, v, w;
cin >> u >> v >> w;
zajiao[u][v] = zajiao[v][u] = w;
int tep = ++fa[w].num;
if (t[u] < t[v])swap(u, v);
fa[w].u[tep] = u;
fa[w].v[tep] = v;
}
}
bool dfs(int x) {
if (fa[x].num == 0)return false;
for (int i = 1; i <= fa[x].num; i++) {
int v = fa[x].v[i];
int u = fa[x].u[i];
if (!have_k[u]) {
if (!dfs(u))continue;
}
if (!have_k[v]) {
if (!dfs(v))continue;
}
if (!fa[x].limtime)
fa[x].limtime = max(fa[u].limtime, fa[v].limtime) + max(t[u], t[v]);
else
fa[x].limtime = min(fa[x].limtime, max(fa[u].limtime, fa[v].limtime) + max(t[u], t[v]));
}
have_k[x] = true;
return true;
}
int main()
{
input();
dfs(goal);
cout << fa[goal].limtime;
return 0;
}
java
import java.util.HashMap;
import java.util.Scanner;
public class Main {
static int n,m,k,t;
static int[] ti; //存储各种子成熟时间
static boolean[] hi; //存储是否已经拥有该种子
//存储某个种子是由哪两个种子杂交而成
static HashMap<Integer, int[]> map = new HashMap<Integer, int[]>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
k = sc.nextInt();
t = sc.nextInt();
ti = new int[n];
hi = new boolean[n];
for (int i = 0; i < n; i++) {
ti[i] = sc.nextInt();
}
for (int i = 0; i < m; i++) {
hi[sc.nextInt() - 1] = true;
}
for (int i = 0; i < k; i++) {
int a = sc.nextInt(),
b = sc.nextInt(),
c = sc.nextInt();
map.put(c, new int[]{a,b});
}
int res = dfs(t);
System.out.println(res);
}
/*
该方法计算拿到种子t所需时间
*/
private static int dfs(int t) {
//如果种子t存在,就返回0
if (hi[t - 1]) {
return 0;
}
//改变一下种子状态,设为已存在
hi[t - 1] = true;
//没有这个种子
//计算获得能够杂交出种子t的种子a和b的时间
int ai = dfs(map.get(t)[0]);
int bi = dfs(map.get(t)[1]);
//计算杂交出种子t的时间
int at = ti[map.get(t)[0] - 1];
int bt = ti[map.get(t)[1] - 1];
//由于获得种子a和b可以同时进行,取耗费时间最大值
//题上说杂交时间取最大值
return Math.max(ai, bi) + Math.max(at,bt);
}
}
python
import os
import sys
# 请在此输入您的代码
input1 = input().split(' ')
input2 = input().split(' ')
# 总类数\初始种子类数\杂交方案数\目标种子编号
N, M, K, T = int(input1[0]), int(input1[1]), int(input1[2]), int(input1[3])
time = {} # 各类:各类生长时间
for i in range(1, N+1):
time[str(i)] = int(input2[i - 1])
input3 = input().split(' ')
H = [] # 已有种类
for i in range(M):
H.append(int(input3[i]))
F_dict = {} # 杂交方案_字典
for i in range(K):
input4 =input().split(' ')
F_dict[input4[2]] = input4[0:2]
out_time = {} # 杂交所需时间
for i in range(1, N+1):
if i in H:
out_time[i] = 0
else:
j = str(i)
m1 = max(int(time[F_dict[j][0]]), int(time[F_dict[j][1]]))
m2 = max(int(out_time[int(F_dict[j][0])]), int(out_time[int(F_dict[j][1])]))
out_time[i] = m1 + m2
print(out_time[T])
标签:杂交,真题,int,蓝桥,fa,2020,种子,time,作物 来源: https://blog.csdn.net/qq_51222650/article/details/115385413