| 语言 | 时间限制 | 内存限制 | 代码长度限制 | 栈限制 |
|---|---|---|---|---|
| Java (javac) | 1700 ms | 512 MB | 16KB | 8192 KB |
| Python (python3) | 1100 ms | 256 MB | 16KB | 8192 KB |
| 其他编译器 | 400 ms | 64 MB | 16KB | 8192 KB |
题目描述:

在新一代智能推理引擎中,一个大语言模型被设计为"逐步思考"的模式。它在回答复杂问题时,会从一个初始想法(称为"根思维节点")出发,每一步都基于当前思路,生成若干个可能的下一步推理方向,每个方向代表一个子想法。我们考虑一个简化的推理策略:当有多个子想法可以继续时,模型选择推理概率最高的子想法尝试展开。如果最高概率有并列,则选择所有想法中编号最小的子想法尝试展开。注意:模型不会重复思考同一个想法,以避免循环推理。所以严格说来,模型在选择下一步推理方向时,保证排除路径中已访问过的想法。一旦某个推理路径走到尽头(即没有新的子想法可生成),就结束本次推理。
本题就请你实现这个推理过程。声明:本题仅限人类解答。
输入格式:
输入第一行给出两个正整数: n ( ≤ 10 4 ) n(\le 10^4) n(≤104)为模型中定义的想法的个数(于是所有的想法从 1 1 1 到 n n n 编号); m ( ≤ 10 n ) m(\le 10n) m(≤10n)为"思维跳跃"关系的数量。随后 m m m 行,每行描述一个"思维跳跃"关系,格式为:
id1 id2 p
表示从编号为 id1 的想法引出编号为 id2 的想法的概率等于 p % \% %。题目保证 id1 和 id2 互不相等,均为合法编号,且任一对关系不会重复给出;p 是区间 [ 1 , 100 ] [1, 100] [1,100] 内的整数。注意:上述"引出"的关系并不是单向的,即" A A A 引出 B B B"并不意味着 B B B 可以引出 A A A 可以引出 B B B。
接下来一行给出正整数 K ( ≤ 100 ) K( \le 100) K(≤100),后面跟着 K K K 个想法编号。
输出格式:
对于输入中给出的 K K K 个想法编号,顺序输出以每个想法为根思维节点的推理路径(包括根思维节点本身)。每个推理路径占一行,相邻想法编号的输出间以 -> 分隔,行首尾不得有多余空格。
输入样例:
10 18
2 3 1
2 1 3
2 6 3
6 2 3
3 1 4
1 6 5
6 1 2
1 4 5
1 5 4
4 5 1
5 6 3
5 7 4
7 4 7
7 8 1
8 9 8
9 7 9
9 5 9
3 8 6
5 2 3 10 6 7
输出样例:
2->1->4->5->7->8->9
3->8->9->5->7->4
10
6->2->1->4->5->7->8->9
7->4->5->6->2->1
给定 m m m 组思维跳跃关系,找到以 每个想法 为根思维节点的推理路径。
- 简化的推理策略
- 当有多个子想法可以继续时,模型选择推理概率最高的子想法尝试展开。
- 如果最高概率有并列,则选择所有想法中编号最小的子想法尝试展开。
- 注意:模型不会重复思考同一个想法,以避免循环推理。
emmmmmmm
图论贪心题目
-
- 由于需要按照推理概率最高 的子想法优先展开,若推理概率相同 ,则选择编号更小的想法展开
- 因此就需要使用结构体排序进行实现。这样可以保证在后续拓展的想法能保证符合该要求。
- 由于需要按照推理概率最高 的子想法优先展开,若推理概率相同 ,则选择编号更小的想法展开
-
- 已知所有想法的拓展都符合题目要求,因此本题就只需要从当前节点出发,找到第一个合法拓展 的子想法即可
- 即便当前节点可拓展的想法有多个,但是最终想法只有一个
- 已知所有想法的拓展都符合题目要求,因此本题就只需要从当前节点出发,找到第一个合法拓展 的子想法即可
- 那么我们可以将其输入的内容先排序,然后再依次存入。每次将节点
d2按照顺序依次存入节点id1就可以了,这样子能保证找到的第一个是概率最高,并且编号最小的。 - 然后每次查询时拿到当前可以拓展的第一个未使用的想法,作为当前想法往下继续拓展即可。
- 直到无法拓展为止。这样就能找到以 每个想法 为根思维节点的推理路径。
java
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main
{
static class edge
{
int id2, p;
public edge(int id2, int p)
{
this.id2 = id2;
this.p = p;
}
}
public static void main(String[] args)
{
int n = sc.nextInt(), m = sc.nextInt();
List<edge>[] mp = new ArrayList[n + 10];
for (int i = 1; i <= n; i++) mp[i] = new ArrayList<>();
for (int i = 1; i <= m; i++)
{
int id1 = sc.nextInt(), id2 = sc.nextInt(), p = sc.nextInt();
mp[id1].add(new edge(id2, p));
}
// 按照p降序, id2升序排列
for (int i = 1; i <= n; i++)
mp[i].sort((a, b) -> a.p != b.p ? b.p - a.p : a.id2 - b.id2);
int k = sc.nextInt();
while (k-- > 0)
{
int x = sc.nextInt();
out.print(x); // 输出第一个想法
boolean[] vis = new boolean[n + 10]; // 存储每个想法是否想过
vis[x] = true;
while (true)
{
int next = -1; // 下一个想法是否存在
for (edge u : mp[x]) // 依次遍历当前想法可以拓展的想法
{
int i = u.id2;
if (!vis[i]) // 如果当前可拓展的想法未被想过
{
next = i; // 记录下一个想法
break;
}
}
if (next == -1) break; // 如果当前想法无法拓展,则退出循环
out.print("->" + next);
vis[next] = true; // 拓展想法标记为想过
x = next; // 替换想法
}
out.println();
}
out.flush();
out.close();
}
static Scanner sc = new Scanner(System.in);
static PrintWriter out = new PrintWriter(System.out);
}
如果有说错的 或者 不懂的 尽管提 嘻嘻
一起进步!!!