JLU数据结构荣誉课——第七次上机实验

JLU数据结构荣誉课——第七次上机实验

7-1 序列调度 (100 分)

在这里插入图片描述

题目分析

模拟法:使用一个栈,在读入输出序列时,若读入的数不是顺序序列对应的数,那顺序序列中的该数应该入栈,若读入的数小于先顺序序列中指向的数,所需的数应在栈中寻找,若在栈顶则可以取得,否则不可取。

代码实现

#include <bits/stdc++.h>
using namespace std;
stack<int>stk;
int main()
{
    int n,m,l=0;
    cin>>n;
    cin>>m;
    for(int i=0;i<m;i++)
    {
        int t,k,zzz=1,lll=0;
        cin>>t;
        if(i!=0)printf("\n");
        while(!stk.empty())stk.pop();
        for(int j=0;j<t;j++)
        {
            int pd=1;//判断标志
           cin>>k;
           if(!stk.empty())
           {
               int yyy=stk.top();
               if(yyy==k)
               {
                   stk.pop();
                   pd=0;
               }
           }
           if(pd)
           {
               if(k==zzz)
               {
                   zzz++;
               }
               else
               while(k!=zzz)
               {
                   stk.push(zzz++);
                   if(stk.size()>=n)
                   {
                       lll=2;
                   }
               }
           }
           if(lll==2)
           {
               printf("No");
               lll++;
           }
           else if(j==t-1&&lll==0)printf("Yes");
        }
    }
}

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

在这里插入图片描述

题目分析

维护两个单调队列,取最大值和最小值,取最大的两个值和最小的两个值依次操作,所得到的便是最大(最小)值。

代码实现

#include<stdio.h>
#include<malloc.h>
#include <bits/stdc++.h>
using namespace std;
struct Node1
{
    long long int value;
    bool operator<(const Node1& a)const
    {
        return value< a.value;
    }
};
struct Node2
{
    long long int value;
    bool operator<(const Node2& a)const
    {
        return value> a.value;
    }
};
priority_queue<Node1> q1;//最大值
priority_queue<Node2> q2;//最小值
int main()
{
    int n,t;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        {
           scanf("%d",&t);
           Node1 t1;
           Node2 t2;
           t1.value=t;
           t2.value=t;
           q1.push(t1);
           q2.push(t2);
        }
 //   if(n==1)printf("%d\n%d",)
    for(int i=0;i<n-1;i++)
    {
        Node1 t1,t2,zz1;
        Node2 t3,t4,zz2;
        t1=q1.top();
        q1.pop();
        t2=q1.top();
        q1.pop();
        zz1.value=(t1.value*t2.value)+1;
        q1.push(zz1);

        t3=q2.top();
        q2.pop();
        t4=q2.top();
        q2.pop();
        zz2.value=(t3.value*t4.value)+1;
        q2.push(zz2);

    }
    long long int answer;
    Node1 t1;
    Node2 t2;
    t1=q1.top();
    t2=q2.top();
    answer=t2.value-t1.value;
    cout<<answer;
}

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

在这里插入图片描述

题目分析

根据中跟序列和先跟序列找根,先在先跟序列中找节点,在中跟序列中位于其左边的是他的左子树内容,右边的是其右子树内容。

代码实现

#include<bits/stdc++.h>
using namespace std;

#define MAX_ 20005
queue<int> que;

int a[MAX_],b[MAX_];
int left_[MAX_],right_[MAX_],v[MAX_];
int n;


int Creat(int a[],int b[],int n){
	int tem_0=a[0],zzz;
	if(n==0)return 0;
	for(zzz=0;zzz<n;zzz++){
		if(b[zzz]==tem_0)
			break;
	}
	left_[tem_0]=Creat(a+1,b,zzz);
	right_[tem_0]=Creat(a+zzz+1,b+zzz+1,n-zzz-1);
	return tem_0;
}
int main(){
	cin>>n;
	que.push(1);
	for(int j=1;j<=n;j++){
		cin>>a[j];
	}
	for(int j=1;j<=n;j++){
		cin>>b[j];
	}
	Creat(a+1,b+1,n);
	for(int j=1;j<=n;j++){
		cin>>v[j];
	}
	while(!que.empty()){
		int omm=que.front();
		que.pop();
		if(left_[omm]){v[left_[omm]]+=v[omm];que.push(left_[omm]);}
		if(right_[omm]){v[right_[omm]]+=v[omm];que.push(right_[omm]);}
	}
	for(int b=1;b<n;b++){
        cout<<v[b]<<" ";
	}
    cout<<v[n]<<endl;

	return 0;
}

7-4 方案计数 (100 分)

在这里插入图片描述

题目分析

拓扑排序,找关键路径,并求关键路径的长度以及条数。

需要注意的是,关键路径的条数最多能达到100位,需要用到大整数加法,乘法。

这道题当时不太会,后来借鉴了大佬的方法,,

代码如下

#include<bits/stdc++.h>
using namespace std;
const int Max=10010;
int num[Max];
int zz[Max];
int a[Max];
queue<int>que;
vector<int>map_[Max];

struct Node {
    int ll;
	int rode[102];
	Node(int zzz=0){
	    ll=zzz;
		memset(rode, 0, sizeof(rode));
	}
	void operator =(const Node& p) {
		for (int j = 0;j < 102;j++)
			rode[j] = p.rode[j];
		ll = p.ll;
	}
	void operator +=(const Node& p) {
		int j, long_0,k=0,l,l0;
		long_0 = p.ll;
		if (ll < long_0) { l = ll; l0 = long_0; }
		else { l = long_0; l0 = ll; }
		for (j = 0;j < l;j++) {
			k = rode[j] + p.rode[j] + k;
			rode[j] = k % 10;
			k = k *10/100;
		}
		for (;j < l0;j++) {
			k = k + rode[j];
			rode[j] = k % 10;
			k = k*10/100;
		}
		if (k!=0)
            rode[j++] = k;
		rode[j] = '\0';
		ll = j;
	}
};
Node s[Max];
int main() {
	int l,n,i;
	int j,k,m,tt=1;
	cin>>n>>m;
	for (j = 1;j <= n;++j) {
		cin>>a[j];
	}
	for (i = 0;i < m;++i) {
		cin>>j>>k;
		map_[j].push_back(k);
		num[k]++;
	}
	for (j = 1;j <n+1;j++)
		if (!num[j]) {
			que.push(j);
			zz[j] = a[j];
			s[j].rode[0] = tt;
			s[j].ll = tt;

		}
	while (!que.empty()) {
		k = que.front();
		que.pop();
		while (!map_[k].empty()) {
			j = map_[k].back();
			map_[k].pop_back();
			num[j]--;
			if (zz[k] + a[j] > zz[j])
			{
				s[j] = s[k];
				zz[j] = zz[k] + a[j];
			}
			else
				if (zz[k] + a[j] == zz[j])
					s[j] += s[k];
			if (!num[j])
				que.push(j);
		}

	}
	for (j = 1;j < n+1;j++)
		if (num[j])
		{
			cout<<"0";
			return 0;
		}
	Node ss;
	int ee=0;
	ee--;
	for (j = 1;j < n+1;j++) {
		if (ee < zz[j])
		{
			ss = s[j];
			ee = zz[j];
		}
		else if (ee == zz[j])
			{
				ss += s[j];
			}
	}
	cout<<ee<<endl;
	l = ss.ll-1;
	for (j = l;j >= 0;j--)
		cout<<ss.rode[j];
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值