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

  • 7-1 序列调度 (100 分)
    • 题目
    • 思路
    • 参考代码
  • 7-2 最大最小差 (100 分)
    • 题目
    • 思路
    • 参考代码
  • 7-3 二叉树最短路径长度 (100 分)
    • 题目
    • 思路
      • 以先根序和中根序构建二叉树
      • 树的最短路径权值和
    • 参考代码
  • 7-4 方案计数 (100 分)
    • 题目
    • 思路
      • 拓扑排序
      • 关键活动
      • 高精度的封装
    • 参考代码

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

思路

使用一个数组a[10001]存储要得到的序列,使用一个栈stack<int> s;模拟1~n的入栈和出栈。
如果,栈顶元素等于要得到的序列的当前首元素,则弹栈s.pop();,且所要求序列后移一位sum++;
直到s.size()>Csum==n分别输出No或Yes。

参考代码

#include <iostream>
#include <stack>
using namespace std;
stack<int> s;
int a[10001];int main()
{int T,C;cin>>T>>C;int n;for(int i=1;i<=T;i++){cin>>n; for(int i=0;i<n;i++) cin>>a[i];int sum=0;//已经得到的数字的总个数int num=1;//计数 while(1){while(sum!=n&&s.empty()!=1&&s.top()==a[sum]){s.pop();sum++;}if(s.size()>C){cout<<"No"<<endl;break;}else s.push(num++);if(sum==n){ cout<<"Yes"<<endl;break;}}}
}

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

思路

这题主要是得找到一个规律,取两小相乘+1,重复执行,会得到max。同理,取两大相乘+1,重复执行,会得到min。
这里,我们可以使用优先级队列进行取两小和两大的操作。

priority_queue<int, vector<int>, less<int>> q1;
priority_queue<int, vector<int>, greater<int>> q2;

其中第一个参数是容器中数据类型(int),第二个参数是容器适配器所依赖的容器类型(vector),第三个参数则是一个用于比较的一元谓词。
主体操作,就是如下代码:出队a,b和入队ab+1。

     a = q1.top();q1.pop();b = q1.top();q1.pop();q1.push(a * b + 1);

至于证明留给读者自行思考,我也不会

参考代码

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
priority_queue<int, vector<int>, less<int>> q1;
priority_queue<int, vector<int>, greater<int>> q2;
int main()
{int n;cin >> n;int x;for (int i = 1; i <= n; i++){cin >> x;q1.push(x);q2.push(x);}int a, b;for (int i = 1; i <= n-1; i++){a = q1.top();q1.pop();b = q1.top();q1.pop();q1.push(a * b + 1);a = q2.top();q2.pop();b = q2.top();q2.pop();q2.push(a * b + 1);}cout << q2.top() - q1.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

思路

以先根序和中根序构建二叉树

首先思考第一个问题,如何使用先序和中序构建二叉树。
举个栗子:
先根序ABCDEF
中根序BDCAFE
先根序中A为根,在中根序中找到A则A的左子树中根序为BDC,右子树中根序为FE,再回到先根序BCDEF找此时的左子树先根序为BCD,右子树先根序为EF。显然,这可以用递归来解决,参考代码如下:

void creat(Tree& T,int* preorder,int* inorder,int now_n)
{if(now_n==0){T=NULL;return ;}//递归出口 int k,i;//找位置 T = new TreeNode;T->data=preorder[0];T->weight=value[preorder[0]];// cout<<*preorder<<" ";for(i = 0; i<now_n; i++)//找位置 if(inorder[i] == preorder[0])break;k=i; creat(T->left,preorder+1,inorder,k);//递归调用本算法创建左子树creat(T->right,preorder+k+1,inorder+k+1,now_n-k-1);//递归调用本算法创建右子树}

树的最短路径权值和

跟打印每条路径的思路差不多,只不过不是打印,而是在遍历时存储并相加每个点的权值得到sum。

void printpath(Tree& T,int sum) {//二叉树中从每个叶子结点到根结点的路径//cout<<s<<" ";if (T != NULL) {int s=sum+T->weight;//将当前结点权值放入路径中ret[T->data]=s;if (T->left == NULL && T->right == NULL) {//叶子结点} else {printpath(T->left,s);printpath(T->right,s);}}
}

参考代码

#include<bits/stdc++.h>
using namespace std;typedef struct node {int data;struct node* left;struct node* right;int weight;
} TreeNode, * Tree;int n;
int preorder[20001];
int inorder[20001];
int value[20001];
int ret[20001];
void creat(Tree& T,int* preorder,int* inorder,int now_n)
{if(now_n==0){T=NULL;return ;}//递归出口 int k,i;//找位置 T = new TreeNode;T->data=preorder[0];T->weight=value[preorder[0]];// cout<<*preorder<<" ";for(i = 0; i<now_n; i++)//找位置 if(inorder[i] == preorder[0])break;k=i; creat(T->left,preorder+1,inorder,k);//递归调用本算法创建左子树creat(T->right,preorder+k+1,inorder+k+1,now_n-k-1);//递归调用本算法创建右子树}void printpath(Tree& T,int sum) {//二叉树中从每个叶子结点到根结点的路径//cout<<s<<" ";if (T != NULL) {int s=sum+T->weight;//将当前结点权值放入路径中ret[T->data]=s;if (T->left == NULL && T->right == NULL) {//叶子结点} else {printpath(T->left,s);printpath(T->right,s);}}
}int main() {cin>>n;for(int i=0; i<n; i++) cin>>preorder[i];for(int i=0; i<n; i++) cin>>inorder[i];for(int i=1; i<=n; i++) cin>>value[i];Tree T;creat(T,preorder,inorder,n);int sum=0;printpath(T,sum);//ret[T->data]=T->weight;for(int i=1;i<n;i++) cout<<ret[i]<<" ";cout<<ret[n]<<endl;
}

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

思路

题目的思路不难,但写起来,却烦的很。由题意不难发现,是一道关于关键路径的题。求关键路径不难,难在求关键方案的数目。还有一点就是,关键方案数是100位数,故还得使用高精度的算法。

拓扑排序

首先,我们得先运用虚源虚汇的方法将点权转化为边权。(就是设个虚源,边权为0,并把每个点的点权后移到对应边上即可)
至于拓扑排序如何进行,在以前的文章中已经讨论过了,在此便不再赘述。(在这次的方法中,使用vector+pair的形式存储,first为该点的邻接点,second为到达该邻接点的边权)

stack<int> s;
int tpxv[10100];
int rudu[10100];
vector<pair<int,int> > v[10100];//first为邻接点,second为权值
void Tpsort(int n)
{s.push(0);//虚源int i=0,j=0;for(i=0;i<=n+1;i++){if(s.empty()==1){cout<<'0'<<'\n';exit(0);}int x=s.top();s.pop();tpxv[j]=x;++j;vector<pair<int,int> >::iterator it=v[x].begin();for(;it!=v[x].end();++it){rudu[it->first]--;if(rudu[it->first]==0)s.push(it->first);}}
}

关键活动

使用正序拓扑序列求一遍各点最早开始时间ve,再使用逆序拓扑序列求一遍最晚开始时间vl。ve=vl的点,即是关键活动点。

int ve[10100];
int vl[10100];
void CriticalPath(int n)
{int i=0;Tpsort(n);for(i=0;i<=n;++i){vector<pair<int,int> >::iterator it=v[tpxv[i]].begin();for(;it!=v[tpxv[i]].end();++it){if(ve[it->first]<ve[tpxv[i]]+it->second)ve[it->first]=ve[tpxv[i]]+it->second; }}for(i=0;i<=n+1;i++) vl[i]=ve[n+1];//逆序求最迟for(i=n;i>=0;--i){vector<pair<int,int> >::iterator it=v[tpxv[i]].begin();for(;it!=v[tpxv[i]].end();++it){if(vl[it->first]<vl[tpxv[i]]+it->second)vl[tpxv[i]]=vl[it->first]-it->second; }}}

高精度的封装

将输出的大数,一位位存储进vector,来个reverse反转一下,就是一位位的大数,具体实现在前几次的题解中的大数加法完全类似,这里只是做了一下封装,故不再赘述。


class GJD//高精度
{public:vector<int> v;//存储高精度数 int flag;//标记 GJD(int=0);GJD operator=(GJD gjd);GJD operator+(GJD gjd);GJD &operator+=(GJD gjd);GJD operator-(GJD gjd);friend ostream &operator<<(ostream &out,GJD &gjd);//~GJD()=0;
};ostream &operator<<(ostream &out,GJD &gjd)
{for(int i=0;i<gjd.v.size();++i) out<<gjd.v.at(i);return out;
}GJD::GJD(int n)
{int temp=n;if(temp==0){flag=0;v.push_back(0);}else{flag=1;while(temp!=0){v.push_back(temp%10);temp=temp/10;}reverse(v.begin(),v.end());}
}
GJD GJD::operator=(GJD gjd)
{v.assign(gjd.v.begin(),gjd.v.end());flag=gjd.flag;return *this;
}GJD GJD::operator+(GJD gjd)
{GJD ret;ret.v.clear();ret.flag=gjd.flag;int i=this->v.size()-1;int j=gjd.v.size()-1;int fg=0;//标记进位 while(i>=0&&j>=0){int temp=this->v.at(i)+gjd.v.at(j);if(fg==1){fg=0;temp=temp+1;};if(temp>=10){fg=1;temp=temp-10;};ret.v.push_back(temp);--i;--j;}while(i>=0){int temp=this->v.at(i);if(fg==1){fg=0;temp=temp+1;};if(temp>=10){fg=1;temp=temp-10;};ret.v.push_back(temp);--i;}while(j>=0){int temp=gjd.v.at(j);if(fg==1){fg=0;temp=temp+1;};if(temp>=10){fg=1;temp=temp-10;};ret.v.push_back(temp);--j;}if(fg==1){ret.v.push_back(1);fg=0;}reverse(ret.v.begin(),ret.v.end());return ret;
}GJD GJD::operator-(GJD gjd)
{GJD ret;ret.v.clear();ret.flag=gjd.flag;int i=this->v.size()-1;int j=gjd.v.size()-1;int fg=0;//标记进位 while(i>=0&&j>=0){int temp=this->v.at(i)-gjd.v.at(j);if(fg==1){fg=0;temp=temp-1;};if(temp<0){fg=1;temp=temp+10;};ret.v.push_back(temp);--i;--j;}while(i>=0){int temp=this->v.at(i);if(fg==1){fg=0;temp=temp-1;};if(temp<0){fg=1;temp=temp+10;};ret.v.push_back(temp);--i;}
//  while(j>=0)
//  {//      int temp=gjd.v.at(j);
//      if(fg==1){fg=0;temp=temp+1;};
//      if(temp>=10){fg=1;temp=temp-10;};
//      ret.v.push_back(temp);
//      --j;
//  }// if(fg==1)
//  {//      ret.v.push_back(1);
//      fg=0;
//  }int f=ret.v.size()-1;while(!ret.v.at(f)){ret.v.pop_back();--f;}reverse(ret.v.begin(),ret.v.end());return ret;
}GJD &GJD::operator+=(GJD gjd)
{*this=*this+gjd;return *this;
}

参考代码

有了上述的关键路径已经高精度算法,只需使用dfs遍历各个关键活动点(ve=vl的点),并在DFS(x)的开始,记录jieguo的值。

#include<bits/stdc++.h>
using namespace std;class GJD//高精度
{public:vector<int> v;//存储高精度数 int flag;//标记 GJD(int=0);GJD operator=(GJD gjd);GJD operator+(GJD gjd);GJD &operator+=(GJD gjd);GJD operator-(GJD gjd);friend ostream &operator<<(ostream &out,GJD &gjd);//~GJD()=0;
};ostream &operator<<(ostream &out,GJD &gjd)
{for(int i=0;i<gjd.v.size();++i) out<<gjd.v.at(i);return out;
}GJD::GJD(int n)
{int temp=n;if(temp==0){flag=0;v.push_back(0);}else{flag=1;while(temp!=0){v.push_back(temp%10);temp=temp/10;}reverse(v.begin(),v.end());}
}
GJD GJD::operator=(GJD gjd)
{v.assign(gjd.v.begin(),gjd.v.end());flag=gjd.flag;return *this;
}GJD GJD::operator+(GJD gjd)
{GJD ret;ret.v.clear();ret.flag=gjd.flag;int i=this->v.size()-1;int j=gjd.v.size()-1;int fg=0;//标记进位 while(i>=0&&j>=0){int temp=this->v.at(i)+gjd.v.at(j);if(fg==1){fg=0;temp=temp+1;};if(temp>=10){fg=1;temp=temp-10;};ret.v.push_back(temp);--i;--j;}while(i>=0){int temp=this->v.at(i);if(fg==1){fg=0;temp=temp+1;};if(temp>=10){fg=1;temp=temp-10;};ret.v.push_back(temp);--i;}while(j>=0){int temp=gjd.v.at(j);if(fg==1){fg=0;temp=temp+1;};if(temp>=10){fg=1;temp=temp-10;};ret.v.push_back(temp);--j;}if(fg==1){ret.v.push_back(1);fg=0;}reverse(ret.v.begin(),ret.v.end());return ret;
}GJD GJD::operator-(GJD gjd)
{GJD ret;ret.v.clear();ret.flag=gjd.flag;int i=this->v.size()-1;int j=gjd.v.size()-1;int fg=0;//标记进位 while(i>=0&&j>=0){int temp=this->v.at(i)-gjd.v.at(j);if(fg==1){fg=0;temp=temp-1;};if(temp<0){fg=1;temp=temp+10;};ret.v.push_back(temp);--i;--j;}while(i>=0){int temp=this->v.at(i);if(fg==1){fg=0;temp=temp-1;};if(temp<0){fg=1;temp=temp+10;};ret.v.push_back(temp);--i;}
//  while(j>=0)
//  {//      int temp=gjd.v.at(j);
//      if(fg==1){fg=0;temp=temp+1;};
//      if(temp>=10){fg=1;temp=temp-10;};
//      ret.v.push_back(temp);
//      --j;
//  }// if(fg==1)
//  {//      ret.v.push_back(1);
//      fg=0;
//  }int f=ret.v.size()-1;while(!ret.v.at(f)){ret.v.pop_back();--f;}reverse(ret.v.begin(),ret.v.end());return ret;
}GJD &GJD::operator+=(GJD gjd)
{*this=*this+gjd;return *this;
}stack<int> s;
int tpxv[10100];
int rudu[10100];
vector<pair<int,int> > v[10100];//first为邻接点,second为权值 void Tpsort(int n)
{s.push(0);//虚源int i=0,j=0;for(i=0;i<=n+1;i++){if(s.empty()==1){cout<<'0'<<'\n';exit(0);}int x=s.top();s.pop();tpxv[j]=x;++j;vector<pair<int,int> >::iterator it=v[x].begin();for(;it!=v[x].end();++it){rudu[it->first]--;if(rudu[it->first]==0)s.push(it->first);}}
}int ve[10100];
int vl[10100];
void CriticalPath(int n)
{int i=0;Tpsort(n);for(i=0;i<=n;++i){vector<pair<int,int> >::iterator it=v[tpxv[i]].begin();for(;it!=v[tpxv[i]].end();++it){if(ve[it->first]<ve[tpxv[i]]+it->second)ve[it->first]=ve[tpxv[i]]+it->second; }}for(i=0;i<=n+1;i++) vl[i]=ve[n+1];//逆序求最迟for(i=n;i>=0;--i){vector<pair<int,int> >::iterator it=v[tpxv[i]].begin();for(;it!=v[tpxv[i]].end();++it){if(vl[it->first]<vl[tpxv[i]]+it->second)vl[tpxv[i]]=vl[it->first]-it->second; }}}GJD jieguo;
GJD vis[10100];void DFS(int x,int n)
{if(x==n+1){jieguo=jieguo+1;return ;}GJD tmp=jieguo;vector<pair<int,int> >::iterator it=v[x].begin();for(;it!=v[x].end();++it)//遍历其所有邻边{if(vis[it->first].flag==1)//如果已经求出其后面的关键路径数{jieguo=jieguo+vis[it->first]-1;continue;}if(ve[it->first]==vl[it->first])//只有ve=vl才是关键路径上的点DFS(it->first,n);}vis[x]=jieguo-tmp+1;}int weight[10100];int main()
{//  ios::sync_with_stdio(0);
//  cin.tie(0);int N,M;cin>>N>>M;for(int i=1;i<=N;i++) cin>>weight[i];int u,V;for(int i=1;i<=M;i++)//初始化 {cin>>u>>V;v[u].push_back(make_pair(V,weight[u]));rudu[V]++;}for(int i=1;i<=N;i++){if(rudu[i]==0){v[0].push_back(make_pair(i,0));rudu[i]++;}}for(int i=1;i<=N;i++){if(v[i].size()==0){v[i].push_back(make_pair(N+1,weight[i]));rudu[N+1]++;}}CriticalPath(N);DFS(0,N);cout<<vl[N+1]<<'\n';cout<<jieguo<<'\n';
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新文章

  1. c语言程序设计自评报告,石家庄学院c语言程序设计自评报告.docx
  2. 《强化学习周刊》第6期:强化学习应用之推荐系统
  3. mysql 1005 错误
  4. window和 linux 在一起 ios和 android在一起 net和js在一起
  5. 钉钉微应用怎么进入_钉钉微应用开发免登流程
  6. Learn Python the Hard Way: 字典
  7. C#中的多线程 - 并行编程 z
  8. 【Java】《Java面向对象编程的三大特性》阅读笔记
  9. python是一种面相什么语言_Python面相对象编程的知识总结
  10. iis 搭建html网站,iis6.0 、7.0添加网站(搭建网站)
  11. 微信小游戏 - 开发工具安装 - 官方 Demo 运行
  12. Netruon 理解(12):使用 Linux bridge 将 Linux network namespace 连接外网
  13. 【20211206】【信号处理】时频分析 —— 短时傅里叶变换(STFT)
  14. 从7654浏览器卸载到安装360安全卫士
  15. 为织梦cms列表页文章缩略图添加alt属性的方法
  16. java用ffmpeg获取音频信息及转化音频采样率、比特率、声道数量、格式
  17. 分享几个关于geoJson的网站(乡镇级地图绘制)
  18. 网页JS获取当前地理位置(省市区)
  19. 数据预处理 拉依达准则 matlab,数学建模数据预处理.doc
  20. poj 1013 模拟 天平问题

热门文章

  1. 解决win10下外接高分辨率显示器显示模糊的问题(和缩放与布局无法调节)
  2. nodejs 调用阿里云短信
  3. 北京市经信委主任王刚一行赴博彦科技调研
  4. 整数划分java_整数划分问题及其算法
  5. eslint-disable-next-line
  6. PDF分割器2.0-可视化操作
  7. VB、WIN32API函数在串口操作模块的运用
  8. Nginx入门使用教程
  9. 基于three.js如何在模型加消息提示框?
  10. 酒店餐饮餐厅点餐系统管理系统项目设计实现与源码附带设计文档