当前位置: 首页 > news >正文

牛客刷题-Day34

今日刷题:\(1001-1004\)

1001 NC16679 [NOIP2003]神经网络

题目描述

人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本神经网络的入门书籍后,提出了一个简化模型,他希望你能帮助他用程序检验这个神经网络模型的实用性。

在兰兰的模型中,神经网络就是一张有向图,图中的节点称为神经元,而且两个神经元之间至多有一条边相连,下图是一个神经元的例子:
image

神经元〔编号为 \(1\)
图中,\(X_1—X_3\) 是信息输入渠道,\(Y_1-Y_2\) 是信息输出渠道,\(C1\) 表示神经元目前的状态,\(U_i\) 是阈值,可视为神经元的一个内在参数。神经元按一定的顺序排列,构成整个神经网络。在兰兰的模型之中,神经网络中的神经无分为几层;称为输入层、输出层,和若干个中间层。每层神经元只向下一层的神经元输出信息,只从上一层神经元接受信息。下图是一个简单的三层神经网络的例子。

兰兰规定,\(C_i\) 服从公式:(其中 \(n\) 是网络中所有神经元的数目)
image

公式中的 \(W_{ji}\)(可能为负值)表示连接 \(j\) 号神经元和 \(i\) 号神经元的边的权值。当 \(C_i\) 大于 \(0\) 时,该神经元处于兴奋状态,否则就处于平静状态。当神经元处于兴奋状态时,下一秒它会向其他神经元传送信号,信号的强度为 \(C_i\)

如此.在输入层神经元被激发之后,整个网络系统就在信息传输的推动下进行运作。现在,给定一个神经网络,及当前输入层神经元的状态(\(C_i\)),要求你的程序运算出最后网络输出层的状态。

输入描述

第一行是两个整数 \(n\)\(1≤n≤200\))和 \(p\)
接下来 \(n\) 行,每行两个整数,第 \(i+1\) 行是神经元i最初状态和其阈值(\(U_i\)),非输入层的神经元开始时状态必然为 \(0\)
再下面 \(P\) 行,每行由两个整数 \(i\)\(j\) 及一个整数 \(W_{ij}\),表示连接神经元 \(i\)\(j\) 的边权值为 \(W_{ij}\)

输出描述

包含若干行,每行有两个整数,分别对应一个神经元的编号,及其最后的状态,两个整数间以空格分隔。
仅输出最后状态非零的输出层神经元状态,并且按照编号由小到大顺序输出!
若输出层的神经元最后状态均为 \(0\),则输出 NULL

示例

输入

5 6
1 0
1 0
0 1
0 1
0 1
1 3 1
1 4 1
1 5 1
2 3 1
2 4 1
2 5 1

输出

3 1
4 1
5 1
解题思路

确定输入层之后,按照拓扑序排序来完成每一层的计算,最后出度为 \(0\) 的即为输出层。

C++ 代码
// NC16679
#include <bits/stdc++.h>
using namespace std;
const int N = 210;int n, m;
struct Node {int c, u, out; // 状态 阈值 出度
} a[N];int g[N][N];
bool flag[N][N];
int in_degree[N];int main() {if (scanf("%d%d", &n, &m) != 2) return 0;queue<int> q;for (int i = 1; i <= n; i++) {scanf("%d%d", &a[i].c, &a[i].u);if (a[i].c > 0) {q.push(i);} else {a[i].c -= a[i].u;}}while (m--) {int i, j, w;scanf("%d%d%d", &i, &j, &w);g[i][j] = w;flag[i][j] = true;in_degree[j]++;a[i].out++;}while (!q.empty()) {int t = q.front();q.pop();if (a[t].c > 0) {for (int j = 1; j <= n; j++) {if (flag[t][j]) {a[j].c += g[t][j] * a[t].c;}}}for (int j = 1; j <= n; j++) {if (flag[t][j]) {in_degree[j]--;if (in_degree[j] == 0) {q.push(j);}}}}int cnt = 0;for (int i = 1; i <= n; i++) {if (a[i].out == 0 && a[i].c > 0) {printf("%d %d\n", i, a[i].c);cnt++;}}if (cnt == 0) puts("NULL");return 0;
}

1002 NC16541 [NOIP2013]车站分级

题目描述

一条单向的铁路线上,依次有编号为 \(1, 2, …, n\) 的 $n $ 个火车站。每个火车站都有一个级别,最低为 \(1\) 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 \(x\),则始发站、终点站之间所有级别大于等于火车站 \(x\) 的都必须停靠。
注意:起始站和终点站自然也算作事先已知需要停靠的站点。

例如,下表是 $ 5 $ 趟车次的运行情况。其中,前 $ 4$ 趟车次均满足要求,而第 \(5\) 趟车次由于停靠了 \(3\) 号火车站(\(2\) 级)却未停靠途经的 \(6\) 号火车站(亦为 \(2\) 级)而不满足要求。

现有 \(m\) 趟车次的运行情况(全部满足要求),试推算这 $ n$ 个火车站至少分为几个不同的级别。

输入描述

第一行包含 \(2\) 个正整数 \(n, m\),用一个空格隔开。
\(i + 1\)\((1 ≤ i ≤ m)\) 中,首先是一个正整数 \(s_i\ (2 ≤ s_i ≤ n)\),表示第 $ i$ 趟车次有 \(s_i\) 个停靠站;接下来有 $ s_i$ 个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。

输出描述

一个正整数,即 \(n\) 个火车站最少划分的级别数。

示例1

输入

9 2 
4 1 3 5 6 
3 3 5 6 

输出

2
示例2

输入

9 3 
4 1 3 5 6 
3 3 5 6 
3 1 5 9 

输出

3
备注

对于 $ 20%$ 的数据,\(1 ≤ n, m ≤ 10\)
对于 \(50\%\) 的数据,\(1 ≤ n, m ≤ 100\)
对于 \(100\%\) 的数据,\(1 ≤ n, m ≤ 1000\)

解题思路

拓扑排序,即对于每列车可以确定其行程里,未经停车站的级别是小于所有经停车站的。因此经过所有的列车行程可以确定一个有向图,该图的节点深度就是级别的最少划分数

C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;int n, m, s;
int g[N][N], d[N], depth[N];
int st[N], p[N];int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++) {memset(st, 0, sizeof st);scanf("%d", &s);for (int j = 1; j <= s; j++) {scanf("%d", &p[j]);st[p[j]] = 1;}for (int j = p[1]; j <= p[s]; j++)if (!st[j])for (int k = 1; k <= s; k++)if (!g[j][p[k]]) {g[j][p[k]] = 1;d[p[k]]++;}}memset(st, 0, sizeof st);queue<int> q;for (int i = 1; i <= n; i++)if (d[i] == 0) {depth[i] = 1;q.push(i);}while (q.size()) {auto t = q.front();st[t] = 1;q.pop();for (int i = 1; i <= n; i++)if (g[t][i] && !st[i]) {d[i]--;if (d[i] == 0) {depth[i] = depth[t] + 1;q.push(i);}}}int ans = 0;for (int i = 1; i <= n; i++)ans = max(ans, depth[i]);printf("%d\n", ans);return 0;
}

1002 NC20115 [HNOI2015]菜肴制作

题目描述

知名美食家小 A 被邀请至 ATM 大酒店,为其品评菜肴。 ATM 酒店为小 A 准备了 \(N\) 道菜肴,酒店按照为菜肴预估的质量从高到低给予 \(1\)\(N\) 的顺序编号,预估质量最高的菜肴编号为 \(1\)

由于菜肴之间口味搭配的问题,某些菜肴必须在另一些菜肴之前制作,具体的,一共有 \(M\) 条形如“\(i\) 号菜肴必须先于 \(j\) 号菜肴制作”的限制,我们将这样的限制简写为 \(<i,j>\)

现在,酒店希望能求出一个最优的菜肴的制作顺序,使得小 A能尽量先吃到质量高的菜肴:

也就是说,

\((1)\) 在满足所有限制的前提下,\(1\) 号菜肴“尽量”优先制作;
\((2)\) 在满足所有限制,\(1\) 号菜肴“尽量”优先制作的前提下,\(2\) 号菜肴“尽量”优先制作;
\((3)\) 在满足所有限制,\(1\) 号和 \(2\) 号菜肴“尽量”优先的前提下,\(3\) 号菜肴“尽量”优先制作;
\((4)\) 在满足所有限制,\(1\) 号和 \(2\) 号和 \(3\) 号菜肴“尽量”优先的前提下,\(4\) 号菜肴“尽量”优先制作;
$(5) $以此类推。
例 1:共 \(4\) 道菜肴,两条限制 \(<3,1>\)\(<4,1>\),那么制作顺序是 \(3,4,1,2\)

例 2:共 \(5\) 道菜肴,两条限制 \(<5,2>\)\(<4,3>\),那么制作顺序是 \(1,5,2,4,3\)

例 1 里,首先考虑 \(1\),因为有限制 \(<3,1>\)\(<4,1>\),所以只有制作完 \(3\)\(4\) 后才能制作 \(1\),而根据 \((3)\)\(3\) 号又应“尽量”比 \(4\) 号优先,所以当前可确定前三道菜的制作顺序是 \(3,4,1\);接下来考虑 \(2\),确定最终的制作顺序是 \(3,4,1,2\)

例 2 里,首先制作 \(1\) 是不违背限制的;接下来考虑 \(2\) 时有 \(<5,2>\) 的限制,所以接下来先制作 \(5\) 再制作 \(2\);接下来考虑 \(3\) 时有 \(<4,3>\) 的限制,所以接下来先制作 \(4\) 再制作 \(3\),从而最终的顺序是 \(1,5,2,4,3\)。 现在你需要求出这个最优的菜肴制作顺序。无解输出 Impossible! (不含引号,首字母大写,其余字母小写)

输入描述

第一行是一个正整数 \(D\),表示数据组数。
接下来是 \(D\) 组数据。
对于每组数据:
第一行两个用空格分开的正整数 \(N\)\(M\),分别表示菜肴数目和制作顺序限制的条目数。
接下来 \(M\) 行,每行两个正整数 \(x,y\),表示 \(x\) 号菜肴必须先于 \(y\) 号菜肴制作的限制。(注意:\(M\) 条限制中可能存在完全相同的限制)

输出描述

输出文件仅包含 \(D\) 行,每行 \(N\) 个整数,表示最优的菜肴制作顺序,或者 Impossible! 表示无解(不含引号)。

示例

输入

3 
5 4 
5 4 
5 3 
4 2 
3 2 
3 3 
1 2 
2 3 
3 1 
5 2 
5 2 
4 3

输出

1 5 3 4 2 
Impossible! 
1 5 2 4 3
备注

\(100\%\) 的数据满足 \(N,M≤100000,D≤3\)

解题思路

按照正常的拓扑序来实现,那么会先输出所有入度为 \(0\) 的点,显然是不符合题意的,以题干里的例 2,顺序会是 \(1,4,5,3,2\),显然不符合要求,因为即使受到限制,序号小的也要先输出。那么可以反过来思考,反向建图,则在排序时,优先处理序号大的点,因为序号大的点需要最后处理,只需要在最后输出答案时反过来输出序列即可

C++ 代码
// NC20115
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;int D, n, m;
int h[N], e[N], ne[N], idx, d[N];
int ans[N];void add(int x, int y) {e[idx] = y;ne[idx] = h[x];h[x] = idx++;
}int main() {scanf("%d", &D);while (D--) {idx = 0;memset(h, -1, sizeof h);memset(d, 0, sizeof d);scanf("%d%d", &n, &m);while (m--) {int x, y;scanf("%d%d", &x, &y);add(y, x);d[x]++;}int cnt = 0;priority_queue<int> q;for (int i = 1; i <= n; i++)if (d[i] == 0)q.push(i);while (!q.empty()) {auto t = q.top();q.pop();ans[++cnt] = t;for (int i = h[t]; i != -1; i = ne[i]) {int j = e[i];d[j]--;if (d[j] == 0)q.push(j);}}if (cnt == n) {for (int i = cnt; i; i--)printf("%d ", ans[i]);printf("\n");} else {puts("Impossible!");}}return 0;
}

1004 NC14352 旅行

题目描述

小 z 放假了,准备到 RRR 城市旅行,其中这个城市有 \(N\) 个旅游景点。小 z 时间有限,只能在三个旅行景点进行游玩。小明租了辆车,司机很善良,说咱不计路程,只要你一次性缴费足够,我就带你走遍 RRR 城。
小 z 很开心,直接就把钱一次性缴足了。然而小 z 心机很重,他想选择的路程尽量长。
然而司机也很聪明,他每次从一个点走到另外一个点的时候都走最短路径。
你能帮帮小 z 吗?
需要保证这三个旅行景点一个作为起点,一个作为中转点一个作为终点。(一共三个景点,并且需要保证这三个景点不能重复).

输入描述

本题包含多组输入,第一行输入一个整数 \(t\),表示测试数据的组数
每组测试数据第一行输入两个数 \(N,M\) 表示 RRR 城一共有的旅游景点的数量,以及 RRR 城中有的路的数量。
接下来 \(M\) 行,每行三个数,\(a\)\(b\)\(c\) 表示从 \(a\) 景点和 \(b\) 景点之间有一条长为 \(c\) 的路
\(t<=40;3<=N,M<=1000;1<=a,b<=N;1<=c<=100\)

输出描述

每组数据包含一行,输出一个数,表示整条路程的路长。
如果找不到可行解,输出 \(-1\).

示例

输入

4
7 7
1 2 100
2 3 100
1 4 4
4 5 6
5 6 10
1 6 4
6 7 8
7 3
1 2 1
1 3 1
1 3 2
7 3
1 2 1
3 4 1
5 6 1
8 9
1 2 1
2 3 1
3 4 1
4 1 1
4 5 1
5 6 1
6 7 1
7 8 1
8 5 1

输出

422
3
-1
9

说明:请注意这是一个稀疏图

解题思路

枚举中间点,求出其到其他点的最短路(司机在两点间会走最短路径),答案是最长的两个最短路之和的最大值。

C++ 代码
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 1010;
typedef pair<int, int> PII;int t, n, m, ans;
int h[N], e[N * 2], ne[N * 2], w[N * 2], idx;
int dist[N];
bool st[N];void add(int a, int b, int c) {e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx++;
}void dijkstra(int u) {memset(dist, 0x3f, sizeof dist);memset(st, 0, sizeof st);dist[u] = 0;priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, u});while (heap.size()) {auto t = heap.top();heap.pop();int ver = t.y, distance = t.x;if (st[ver])continue;st[ver] = true;for(int i = h[ver]; i != -1; i = ne[i]) {int j = e[i];if(dist[j] > dist[ver] + w[i]){dist[j] = dist[ver] + w[i];heap.push({dist[j], j});}}}
}int main() {scanf("%d", &t);while (t--) {idx = 0;ans = -1;memset(h, -1, sizeof h);scanf("%d%d", &n, &m);while (m--) {int a, b, c;scanf("%d%d%d", &a, &b, &c);add(a, b, c);add(b, a, c);}for (int i = 1; i <= n; i++) { // 枚举中间点dijkstra(i);int a = 0, b = 0;for (int j = 1; j <= n; j++) {if (dist[j] == 0x3f3f3f3f)continue;if (dist[j] > a) {b = a;a = dist[j];} else if (dist[j] > b) {b = dist[j];}}if (a && b)ans = max(ans, a + b);}printf("%d\n", ans);}return 0;
}
http://www.jsqmd.com/news/442459/

相关文章:

  • 【开题答辩全过程】以 基于大数据分析的手机产品推荐系统为例,包含答辩的问题和答案
  • python+flask的智慧农场农用工具商城管理系统vue农具
  • 支付网关服务架构设计
  • 2026年GEO优化方案推荐,广州深圳地区靠谱的品牌有哪些 - 工业品网
  • 【开题答辩全过程】以 基于springBoot微服务架构的老年人社交系统的设计与实现为例,包含答辩的问题和答案
  • 基于IP地址数据的网络性能优化实践
  • 毕业论文初稿怎么写?5款写论文的AI排行榜,轻松掌握毕业论文! - 掌桥科研-AI论文写作
  • Autojs基础-悬浮窗(floaty)
  • IP归属地数据赋能在线用户匹配:构建精准、高效的社交连接
  • AI专著撰写新玩法!揭秘高效工具,让专著写作不再是难题
  • 计算机毕业设计java基于JAVA的渝行旅游热点推荐系统 基于SpringBoot的重庆旅游智能推荐与攻略服务平台设计 渝行文旅信息整合与个性化推荐系统的研发
  • 用 OpenClaw + DeepSeek + Ollama 自动 Review Spring Boot 项目代码
  • LangChain工作流集成:LongCat-Image-Editn V2智能图像生成
  • 一篇文章带你搞懂“设计模式”! - - 观察者模式(17)
  • 从零开始开发 CNBlog MCP 工具
  • Z-BlogPHP版本历史 zblog网站常见问题1.7 Tenet修复
  • Qwen-Image-2512-Pixel-Art-LoRA效果展示:多主体交互场景像素化逻辑验证
  • 北京搬家公司服务哪家好?盘点5家口碑与实力并存的日式搬家品牌 - 资讯焦点
  • sudo权限添加
  • 2026 年证券纠纷律师专业实力排行榜 - 资讯焦点
  • 高价 + 安全 + 快速:卡券回收平台优选名单(2026 最新) - 资讯焦点
  • 【开题答辩全过程】以 基于SpringBoot私人牙医管理系统的设计与实现为例,包含答辩的问题和答案
  • Z-BlogPHP网站的c_option.php配置文件在哪里zblog网站常见问题
  • 高新能源渗透率园区源网荷储一体化规划及智慧能源管理系统 安科瑞 王文杰
  • 实战演练:用 CrewAI 搭建一套自动化的自媒体内容创作流水线
  • 【光纤通信】10 Gbps正交相位移键控QPSK光纤通信系统(真实的光纤损伤并分析系统在不同条件下的性能)【含Matlab源码 15103期】
  • VPS
  • 工商业储能升级新选择:Acrel-2000ESGXW 能量管理系统,赋能储能价值进阶 安科瑞 王文杰
  • SiameseUIE惊艳案例:含标点/数字/英文混排文本的稳定抽取
  • PHP抽象的核心概念的庖丁解牛