7-1 序列调度 (100 分)

有一个N个数的序列A:1,2,……,N。有一个后进先出容器D,容器的容量为C。如果给出一个由1到N组成的序列,那么可否由A使用容器D的插入和删除操作得到。

输入格式:

第1行,2个整数T和C,空格分隔,分别表示询问的组数和容器的容量,1≤T≤10,1≤C≤N。

第2到T+1行,每行的第1个整数N,表示序列的元素数,1≤N≤10000。接下来N个整数,表示询问的序列。

输出格式:

T行。若第i组的序列能得到,第i行输出Yes;否则,第i行输出No,1≤i≤T。

输入样例:

在这里给出一组输入。例如:

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

输出样例:

在这里给出相应的输出。例如:

No
Yes

作者 谷方明

单位 吉林大学

代码长度限制 16 KB

时间限制 100 ms

内存限制 10 MB

解法一:

思路:

解决本题使用模拟的方法会很好,使用两个指针(下标指针),一个指针A指向待查询序列,一个指针B指向原始序列,A从前向后指向当前待验证序列的各个元素,有两种情况符合要求:每次指向一个元素,若栈顶元素正好与之对应,则弹出,若栈顶元素小于当前A指向的元素,则移动B将原始序列入栈到当前B指向的元素为止,若这两个判断失败,则代表查询失败。

外层用while循环控制,循环条件为栈的元素数小于等于给定的最大栈容量,若出循环则失败,循环内判断B指针是否走到了待查询序列尽头,若是则成功并结束函数。

反思:一看到这个题就想用dfs把所有可能的序列穷尽,然后再比较,还想保存之前运行dfs的结果以便N相同时直接查询。看来纯属是自讨苦吃。首先dfs在这个题不好写,其次要保存结果支持查询也不好写。有时候感受到当前方法不可行了,就要立即切换,不要一条道走到黑。

代码实现:

#include <iostream>
#include <vector>
using namespace std;
vector <int> stk;
int T = 0, C = 0, N = 0;
int* shu=NULL;
int* chaxun = NULL;
void ceshi(){stk.push_back(-1);int cxpoint = 0, shupoint = 1;while (stk.size() < C+2) {//不能超过栈的最大容量if (chaxun[cxpoint] == stk.back()) {//相等弹栈stk.pop_back();cxpoint++;}else if (chaxun[cxpoint] > stk.back()) {//当前指向的数大于栈顶元素(栈顶元素始终最大)则从初始序列中选取元素入栈直到当前查询的元素for (shupoint; shupoint < chaxun[cxpoint] + 1; shupoint++) {stk.push_back(shu[shupoint]);}}else {printf("No\n");return;}if (cxpoint == N - 1) {printf("Yes\n");return;}}printf("No\n");
}
int main() {scanf("%d%d", &T, &C);shu = new int[10001];chaxun = new int[10000];for (int i = 0; i < 10001; i++){shu[i] = i;}for (int i = 0; i < T; i++) {scanf("%d", &N);for (int i = 0; i < N; i++) {scanf("%d", &chaxun[i]);}ceshi();stk.clear();}
}

7-2 最大最小差 (100 分)

对n 个正整数,进行如下操作:每一次删去其中两个数 a 和 b,然后加入一个新数:a*b+1,如此下去直到 只剩下一个数。所有按这种操作方式最后得到的数中,最大的为max,最小的为min,计算max-min。

输入格式:

第1行:n,数列元素的个数,1<=n<=16。

第2行:n 个用空格隔开的数x,x<=10。

输出格式:

1行,所求max-min。

输入样例:

在这里给出一组输入。例如:

3
2 4 3

输出样例:

在这里给出相应的输出。例如:

2

作者 谷方明

单位 吉林大学

代码长度限制 16 KB

时间限制 100 ms

内存限制 64 MB

解法一:

思路:

本题应当发现:若要查找最小元素,则要每次选最小的两个元素进行操作,最大亦然。

这让我想到了哈夫曼树的建树思路。

有两种办法:

1.大小根堆。

2.一次排序。

3.利用huffman树建树的方法,在一个数组中多次操作。

反思:这道题我又想用dfs。。。写起来倒是不难,结果运行起来时间复杂度爆炸式增长,到数据量到10以上基本上就跑很久都跑不出来了。然而我还想着应该是剪枝没有做好,一直在想办法剪枝优化。却忽略了那么简单自然的做法。有的题可能就是靠发现规律来解决的,而不是主要利用已有的结构和方法。

代码实现:

#include <iostream>
#include <queue>
using namespace std;
priority_queue<int,vector<int>,less<int>> small_dl;
priority_queue<int, vector<int>, greater<int>> big_dl;
int main() {int n = 0, cup = 0;scanf("%d", &n);for (int i = 0; i < n; i++) {scanf("%d", &cup);small_dl.push(cup);big_dl.push(cup);}for (int i = 0; i < n-1; i++) {cup = small_dl.top(); small_dl.pop();cup *= small_dl.top(); small_dl.pop();small_dl.push(++cup);cup = big_dl.top(); big_dl.pop();cup *= big_dl.top(); big_dl.pop();big_dl.push(++cup);}printf("%d", big_dl.top() - small_dl.top());
}

7-3 二叉树最短路径长度 (100 分)

给定一棵二叉树T,每个结点赋一个权值。计算从根结点到所有结点的最短路径长度。路径长度定义为:路径上的每个顶点的权值和。

输入格式:

第1行,1个整数n,表示二叉树T的结点数,结点编号1..n,1≤n≤20000。

第2行,n个整数,空格分隔,表示T的先根序列,序列中结点用编号表示。

第3行,n个整数,空格分隔,表示T的中根序列,序列中结点用编号表示。

第4行,n个整数Wi,空格分隔,表示T中结点的权值,-10000≤Wi≤10000,1≤i≤n。

输出格式:

1行,n个整数,表示根结点到其它所有结点的最短路径长度。

输入样例:

在这里给出一组输入。例如:

4
1 2 4 3
4 2 1 3
1 -1 2 3

输出样例:

在这里给出相应的输出。例如:

1 0 3 3

作者 谷方明

单位 吉林大学

代码长度限制 16 KB

时间限制 1000 ms

内存限制 10 MB

解法一:

思路:

本题如果能够发现根结点到某个结点的路径只有一条,将会很简单。

只需要在建树的同时按照给定的权值将路径算出来,也不需要虚源虚汇,直接找父亲的权加自己的权即可。

我还尝试了使用虚汇和不使用的情况下的基本优化Bellman—Ford算法。但是倒数第二个点超时,当时还犹豫了一下要不要优化,不过考虑到如果是特意卡Bellman—Ford的话SPFA也不会有什么变化。还是选择换方法。最后果然证明倒数第二个点数据量比最后一个小很多,就是专门用来卡Bellman—Ford的。

代码实现:

(里面可以看到Bellman—Ford的影子)

#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
#define INT_MAX 1<<28;
int* quan = NULL;
struct TreeNode {int val;int lenth;TreeNode* left;TreeNode* right;TreeNode() : val(0), left(nullptr), right(nullptr) {}TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
};
vector<vector<pair<int, int>>> tu;
TreeNode** yingshe = NULL;
class Build {
public:TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {int preb = 0, pree = preorder.size() - 1;int inb = 0, ine = inorder.size() - 1;return mybuildtree(preorder, inorder, preb, pree, inb, ine,0);}TreeNode* mybuildtree(vector<int>& preorder, vector<int>& inorder, int preb, int pree, int inb, int ine,int lenth) {if (preorder.size() == 0) {return NULL;}if (pree == preb) {TreeNode* root = new TreeNode(preorder[preb]);root->lenth = lenth + quan[root->val];yingshe[root->val] = root;return root;}if (preb > pree || inb > ine) {return NULL;}vector<int>::iterator it;it = inorder.begin();int j = 0;for (j = 0; j < inb; j++) {++it;}int i = 0;while (*it != preorder[preb]) {++it;++i;}TreeNode* root = new TreeNode(preorder[preb]);root->left = mybuildtree(preorder, inorder, preb + 1, preb + i, inb, i + inb - 1,lenth+quan[root->val]);root->right = mybuildtree(preorder, inorder, preb + i + 1, pree, i + inb + 1, ine,lenth+quan[root->val]);root->lenth = lenth + quan[root->val];//关键,建树的时候算lenthyingshe[root->val] = root;//if (root->left)tu[root->val].push_back(make_pair(root->left->val, quan[root->val]));//if (root->right)tu[root->val].push_back(make_pair(root->right->val, quan[root->val]));return root;}
};
/*int* Bellman_Ford(TreeNode*root,int n) {int* dist = new int[n + 1];for (int i = 0; i < n + 1; i++) {dist[i] = INT_MAX;}dist[root->val] = 0;bool flag = false;for (int k = 0; k < n; k++) {flag = false;for (int i = 1; i < n + 1; i++) {for (int j = 0; j < tu[i].size(); j++) {if (dist[i] + tu[i][j].second < dist[tu[i][j].first]) {dist[tu[i][j].first] = dist[i] + tu[i][j].second;flag = true;}}if (flag) {break;}}}return dist;
}*/
/*
void travel(TreeNode* root,int n) {if (root == NULL) {return;}if(root->left)tu[root->val].push_back(make_pair(root->left->val, quan[root->val]));if(root->right)tu[root->val].push_back(make_pair(root->right->val, quan[root->val]));travel(root->left,n);travel(root->right,n);
}*/
int main() {Build a;int n = 0;int cup = 0;scanf("%d", &n);yingshe = new TreeNode * [n + 1];quan = new int[n + 1];//tu = vector<vector<pair<int, int>>>(n + 1);vector<int> preorder(n), inorder(n);for (int i = 0; i < n; i++) {scanf("%d", &cup);preorder[i] = cup;}for (int i = 0; i < n; i++) {scanf("%d", &cup);inorder[i] = cup;}for (int i = 1; i < n+1; i++) {scanf("%d", &quan[i]);}TreeNode* root=a.buildTree(preorder,inorder);//travel(root,n);//int* ans = Bellman_Ford(root,n);/*for (int i = 1; i < n + 1; i++) {printf("%d", ans[i]+quan[i]);if (i < n) {printf(" ");}}*/for (int i = 1; i < n + 1; i++) {printf("%d", yingshe[i]->lenth);if (i < n) {printf(" ");}}
}

7-4 方案计数 (100 分)

组装一个产品需要 n 个零件。生产每个零件都需花费一定的时间。零件的生产可以并行进行。有些零件的生产有先后关系,只有一个零件的之前的所有零件都生产完毕,才能开始生产这个零件。如何合理安排工序,才能在最少的时间内完成所有零件的生产。在保证最少时间情况下,关键方案有多少种,关键方案是指从生产开始时间到结束时间的一个零件生产序列,序列中相邻两个零件的关系属于事先给出的零件间先后关系的集合,序列中的每一个零件的生产都不能延期。

输入格式:

第1行,2个整数n和m,用空格分隔,分别表示零件数和关系数,零件编号1..n,1≤n≤10000, 0≤m≤100000 。

第2行,n个整数Ti,用空格分隔,表示零件i的生产时间,1≤i≤n,1≤Ti≤100 。

第3到m+2行,每行两个整数i和j,用空格分隔,表示零件i要在零件j之前生产。

输出格式:

第1行,1个整数,完成生产的最少时间。

第2行,1个整数,关键方案数,最多100位。

如果生产不能完成,只输出1行,包含1个整数0.

输入样例:

在这里给出一组输入。例如:

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

输出样例:

在这里给出相应的输出。例如:

4
2

作者 谷方明

单位 吉林大学

代码长度限制 16 KB

时间限制 200 ms

内存限制 64 MB

解法一:

思路:

类似于计算最短路条数的思想,一边拓扑排序一边访问结点,由于活动在点上,如果活动的最早开始时间可以被更新就更新,若找到一个不能被更新的就看看是否相等,相等就累加其条数。其中记录到达每个结点的最短路条数用string数组配合大数加法来实现。

代码实现:

#include<iostream>
#include<vector>
#include<queue>
using  namespace std;
string add(string a, string b) {vector<char> cup;int cuppp = 0;int jinwei = 0;char cupa = '0', cupb = '0';while (!a.empty() || !b.empty()) {if (!a.empty()) {cupa = a.back();a.pop_back();}else {cupa = '0';}if (!b.empty()) {cupb = b.back();b.pop_back();}else {cupb = '0';}cuppp = cupa + cupb - 2 * '0' + jinwei;if (cuppp < 10) {cup.push_back(cuppp % 10 + '0');jinwei = 0;}else {cup.push_back(cuppp % 10 + '0');jinwei = 1;}}if (jinwei == 1) {cup.push_back('1');}string ans(cup.rbegin(), cup.rend());return ans;
}
string dashu[10002];
vector<int> tu[10002];
int main(void) {ios::sync_with_stdio(false);//加速cin coutint rudu[10002];int daijia[10002];int sumdaijia[10002];int n = 0, m = 0;int p = 0, q = 0;cin >> n >> m;for (int i = 1; i <= n; i++) {cin >> sumdaijia[i];}for (int i = 0; i < m; i++) {cin >> p >> q;tu[p].push_back(q);rudu[q]++;}queue<int> dl;for (int i = 1; i <= n; i++) {if (0 == rudu[i]) {daijia[i] = sumdaijia[i];dl.push(i);dashu[i] = "1";}}int j;int now = 0;while (!dl.empty()) {now = dl.front();dl.pop();while (tu[now].size()!=0) {j = tu[now].back(); tu[now].pop_back();rudu[j]--;if (0 == rudu[j])dl.push(j);if (daijia[now] + sumdaijia[j] > daijia[j]) {dashu[j] = dashu[now];daijia[j] = daijia[now] + sumdaijia[j];}else if (daijia[now] + sumdaijia[j] == daijia[j]) {dashu[j] = add(dashu[j], dashu[now]);}}}for (int i = 1; i <= n; i++) {if (1 == rudu[i]) {cout<<"0";exit(0);}}string ans("0"); int  lenth = -1;for (int i = 1; i <= n; ++i) {if (lenth < daijia[i]) {ans = dashu[i];lenth = daijia[i];}else if (lenth == daijia[i]) {ans = add(ans, dashu[i]);}}cout << lenth <<"\n";cout << ans;}

JLU数据结构第七次上机实验解题报告相关推荐

  1. 数据结构第七次上机实验-解题报告

    数据结构第七次上机实验-解题报告 7-1 序列调度 (100 分) 题目 思路 参考代码 7-2 最大最小差 (100 分) 题目 思路 参考代码 7-3 二叉树最短路径长度 (100 分) 题目 思 ...

  2. JLU第三次数据结构上机实验解题报告

    T1:二叉树最长路径 题目 给定一棵二叉树T,求T中的最长路径的长度,并输出此路径上各结点的值.若有多条最长路径,输出最右侧的那条. INPUT 第1行,1个整数n,表示二叉树有n个结点. 第2行,2 ...

  3. 数据结构第七次上机实验报告

    7-1 序列调度 有一个N个数的序列A:1,2,--,N.有一个后进先出容器D,容器的容量为C.如果给出一个由1到N组成的序列,那么可否由A使用容器D的插入和删除操作得到. 输入格式: 第1行,2个整 ...

  4. 数据结构荣誉课-第一次实验-解题报告

    JLU-数据结构荣誉课-第一次实验-解题报告 一.重复计数 题目 思路 参考代码 二.报数游戏 题目 思路 参考代码 三.算术表达式计算 题目 思路 参考代码 四.最喜爱的序列 题目 思路 单调队列 ...

  5. 分数计算器java报告_20182307 2019-2020-1 《数据结构与面向对象程序设计》实验四报告...

    20182307 2019-2020-1 <数据结构与面向对象程序设计>实验四报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 陆彦杰 学号:20182307 实验 ...

  6. 20182326 2019-2020-1 《数据结构与面向对象程序设计》实验三报告

    20182326 2019-2020-1 <数据结构与面向对象程序设计>实验三报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 刘颖洁 学号:20182326 实验 ...

  7. 数据结构第六次上机实验

    7-1 高精度数加法 (100 分) 高精度数是指大大超出了标准数据类型能表示的范围的数,例如10000位整数.很多计算问题的结果都很大,因此,高精度数极其重要. 一般使用一个数组来存储高精度数的所有 ...

  8. 数据结构树的基本操作_[数据结构]树的建立与基本操作 解题报告

    Problem Description 在本实验中,程序的输入是一个表示树结构的广义表.假设树的根为 root ,其子树森林 F = ( T1 , T2 , ... , Tn ),设与该树对应的广义表 ...

  9. 数据库原理上机实验内容报告代码

    --创建数据表 create table stu_info( stu_id char(10) not null constraint pk_stu_id primary key,--主键 name n ...

  10. 上海交通大学python实验七答案_20192310 实验八《数据结构与面向对象程序设计》实验报告...

    20192310 2020-2021-1 <数据结构与面向对象程序设计>实验八报告 课程:<程序设计与数据结构> 班级: 1923 姓名: 严嘉钰 学号: 20192310 实 ...

最新文章

  1. Android Zxing 加入闪光灯功能
  2. java阿里数据库连接池_Java学习:数据库连接池技术
  3. 最短Hamilton路径(位运算基本思路)
  4. Leetcode学习成长记:天池leetcode基础训练营Task02链表
  5. java替代重定向_一个简单的java重定向程序,为什么要恢复System . out 对象,却不要恢复System...
  6. 剪贴板增强工具 Ditto
  7. 投资为什么很难进步——越不懂 越自信︱投资道
  8. 2008年管理软件行业的七大趋势预测
  9. 加密狗工作原理和破解方法简介
  10. 如何获得onblur中的值_js中onfocus、onblur事件
  11. 转-- 一位存储研发者的图书清单
  12. matlab求解外推法和黄金分割法
  13. SKY65723-81低噪声放大器前端模块 GPS / GNSS / BDS预过滤器
  14. 原来当年发葫芦娃种子的才是真正的老司机
  15. 桥梁远景图微型计算机教案,桥梁远景图的教案设计
  16. sqlserver 与access,excel互相导入导出代码
  17. 基于深度学习lstm_基于LSTM的深度恶意软件分析
  18. C2P工业云签署,实现无纸化,提高投资回报率
  19. 我不会是亚瑟王,但我想成为梅林
  20. 同一个Maven项目移机出错解决办法

热门文章

  1. 虚拟打印机 android版,Doro PDF Writer
  2. Vensim学习之Random Normal函数的使用
  3. java实战项目教程
  4. 网页设计中常用的Web安全字体
  5. 一个好用的不基于时间的同步文件的软件 —— Allway sync 文件同步
  6. 4k显卡视频测试软件,4K分辨率下体验测试
  7. bzero 和 memset 函数对比
  8. 搭建IPv6网络环境
  9. (原创)用cmd命令制作恶搞程序
  10. offer拿到手软,java分布式面试题及答案