数据结构第二次实验报告 55200213朱展辉

数列查询 (100 分)

题目

已知数列的通项公式为:

 f(n) = f(n-1)*11/10,f[1]=10.

通项从左向右计算,*和/分别表示整数乘法和除法。 现在,要多次查询数列项的值。

输入格式:
第1行,1个整数q,表示查询的次数, 1≤q≤10000. 第2至q+1行,每行1个整数i,表示要查询f(i)的值。

输出格式:
q行,每行1个整数,表示f(i)的值。查询的值都在32位整数范围内。

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

3
1
2
3
输出样例:
在这里给出相应的输出。例如:

10
11
12

思路

第一题,我使用了打表的做法,即先把题目所需长度的函数值存在数组中,当下面输入指定数字时,即可输出函数值,节省了时间。

注意!:
不能用endl,cin,cout,要用‘\n’,scanf,printf来替换。

代码

#include<iostream>
#define endl "\n"
using namespace std;
int main(){
     int a[10000];
	a[0]=10;
	  int i;
	  int q;
    ios::sync_with_stdio(false);
    cin.tie(0);
	cin>>q;
	for(i=1;i<=200;i++){
		a[i]=a[i-1]*11/10;
	}
   int temp;
	for(i=0;i<q;i++){
		cin>>temp;
		cout<<a[temp-1]<<"\n";
	}
	return 0;
}

稀疏矩阵之和 (100 分)

题目

矩阵A和B都是稀疏矩阵。请计算矩阵的和A+B.如果A、B不能做和,输出“Illegal!”

输入格式:
矩阵的输入采用三元组表示,先A后B。对每个矩阵:

第1行,3个整数N、M、t,用空格分隔,分别表示矩阵的行数、列数和非0数据项数,10≤N、M≤50000,t≤min(N,M).

第2至t+1行,每行3个整数r、c、v,用空格分隔,表示矩阵r行c列的位置是非0数据项v, v在32位有符号整型范围内。三元组默认按行列排序。

输出格式:
矩阵A+B,采用三元组表示,默认按行列排序,非零项也在32位有符号整型范围内。

输入样例:
10 10 3
2 2 2
5 5 5
10 10 20
10 10 2
2 2 1
6 6 6
输出样例:
10 10 4
2 2 3
5 5 5
6 6 6
10 10 20

思路

第二题,我使用了两个结构体来存储三元组,并且要注意排序的方式,我使用了sort排序并且自定义cmp函数的方式完成了排序,之后就是列举所有可能发生的情况,并且最终得出结果。

注意!:
1.要注意如果两个矩阵中有和为0的情况,要在生成的矩阵中把那一项去掉。
2.注意排序的方式,先行后列。
3.注意输出不合法的情况。

代码

#include<iostream>
#include<algorithm>
#define endl "\n"
using namespace std;
int maxn=99999;

struct syz{
    int row;
    int col;
    int d;
};
struct all{
    int r;
    int c;
    int num;
    syz n[50001];
};

bool cmp(syz a,syz b){
    if(a.row!=b.row) return a.row<b.row;
    else return a.col<b.col;
}

bool init(all &m){
    int r,c,numq;
    cin>>r>>c>>numq;
    m.r=r;
    m.c=c;
    m.num=0;
    while(numq){
        int x1,x2,x3;
        cin>>x1>>x2>>x3;
        if(x1>m.r||x1<=0||x2>m.c||x2<=0){
            return 0;
        }
        m.n[m.num].row=x1;
        m.n[m.num].col=x2;
        m.n[m.num].d=x3;
        m.num++;
        numq--;
    }
    sort(m.n,m.n+m.num,cmp);
    return 1;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    all m;
    all n;
    all temp;
    if(!init(m)){
        cout<<"Illegal!";
        return 0;
    }
    if(!init(n)){
        cout<<"Illegal!";
        return 0;
    }
    int temp1=0,temp2=0,temp3=0;
    if(m.r!=n.r||m.c!=n.c){
        cout<<"Illegal!"<<endl;
        return 0;
    }
    temp.r=m.r;
    temp.c=m.c;
    while(temp1<m.num||temp2<n.num){
        if(temp1<m.num&&temp2<n.num&&m.n[temp1].row<n.n[temp2].row){
            temp.n[temp3].row=m.n[temp1].row;
            temp.n[temp3].col=m.n[temp1].col;
            temp.n[temp3].d=m.n[temp1].d;
            temp1++;
            temp3++;

        }
        else if(temp1<m.num&&temp2<n.num&&m.n[temp1].row==n.n[temp2].row){

            if(m.n[temp1].col<n.n[temp2].col){
                temp.n[temp3].row=m.n[temp1].row;
                temp.n[temp3].col=m.n[temp1].col;
                temp.n[temp3].d=m.n[temp1].d;
                temp1++;
                temp3++;
            }
            else if(temp1<m.num&&temp2<n.num&&m.n[temp1].col==n.n[temp2].col){
                int q=temp.n[temp3].d=m.n[temp1].d+n.n[temp2].d;
                if(q){
                    temp.n[temp3].row=m.n[temp1].row;
                    temp.n[temp3].col=m.n[temp1].col;
                    temp.n[temp3].d=m.n[temp1].d+n.n[temp2].d;
                    temp3++;
                }
                temp1++;
                temp2++;
            }
            else if(temp1<m.num&&temp2<n.num){
                temp.n[temp3].row=n.n[temp2].row;
                temp.n[temp3].col=n.n[temp2].col;
                temp.n[temp3].d=n.n[temp2].d;
                temp3++;
                temp2++;
            }
        }
        else if(temp1<m.num&&temp2<n.num){
            temp.n[temp3].row=n.n[temp2].row;
            temp.n[temp3].col=n.n[temp2].col;
            temp.n[temp3].d=n.n[temp2].d;
            temp3++;
            temp2++;
        }
        else if(temp1==m.num){
            temp.n[temp3].row=n.n[temp2].row;
            temp.n[temp3].col=n.n[temp2].col;
            temp.n[temp3].d=n.n[temp2].d;
            temp3++;
            temp2++;

        }
        else if(temp2==n.num){
            temp.n[temp3].row=m.n[temp1].row;
            temp.n[temp3].col=m.n[temp1].col;
            temp.n[temp3].d=m.n[temp1].d;
            temp1++;
            temp3++;
        }
    }
    temp.num=temp3;
    cout<<temp.r<<" "<<temp.c<<" "<<temp.num<<endl;
    for(int i=0;i<temp.num;++i){
        cout<<temp.n[i].row<<" "<<temp.n[i].col<<" "<<temp.n[i].d<<endl;
    }
    return 0;
}


文字编辑 (100 分)

题目

一篇文章由n个汉字构成,汉字从前到后依次编号为1,2,……,n。 有四种操作:

A i j表示把编号为i的汉字移动编号为j的汉字之前;

B i j表示把编号为i的汉字移动编号为j的汉字之后;

Q 0 i为询问编号为i的汉字之前的汉字的编号;

Q 1 i为询问编号为i的汉字之后的汉字的编号。

规定:1号汉字之前是n号汉字,n号汉字之后是1号汉字。

输入格式:
第1行,1个整数T,表示有T组测试数据, 1≤T≤9999.

随后的每一组测试数据中,第1行两个整数n和m,用空格分隔,分别代表汉字数和操作数,2≤n≤9999,1≤m≤9999;第2至m+1行,每行包含3个常量s、i和j,用空格分隔,s代表操作的类型,若s为A或B,则i和j表示汉字的编号,若s为Q,i代表0或1,j代表汉字的编号。

输出格式:
若干行,每行1个整数,对应每个询问的结果汉字编号。

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

1
9999 4
B 1 2
A 3 9999
Q 1 1
Q 0 3
输出样例:
在这里给出相应的输出。例如:

4
9998

思路

第三题,一开始不会,后来参考了大佬的代码,得知是跳舞链问题。

代码

#include<iostream>
using namespace std;
int main(){
int T;
int l[10001];
int r[10001];
char oper[3];
int x,y;
ios::sync_with_stdio(false);
cin.tie(0);
cin>>T;
int H,C;
for(int i=T;i>0;--i){
    cin>>H>>C;
    for(int j=1;j<=H;++j){
        l[j]=j-1; //l数组为前驱的序号
        r[j]=j+1; //r数组为后继的序号
    }
    l[1]=H;
    r[H]=1;
    for(int k=C;k>0;--k){
        cin>>oper;
        cin>>x>>y;
        if(oper[0]=='A'){
                r[l[x]]=r[x];
                l[r[x]]=l[x];
                r[x]=y;
                l[x]=l[y];
                r[l[x]]=x;
                l[r[x]]=x;
        }
        else if(oper[0]=='B'){
                r[l[x]]=r[x];
                l[r[x]]=l[x];
                l[x]=y;
                r[x]=r[y];
                r[l[x]]=x;
                l[r[x]]=x;
        }
        else{
            if(x==0){
                cout<<l[y]<<"\n";
            }
            else cout<<r[y]<<"\n";
        }

    }
}
	return 0;
}


幸福指数 (100 分)

题目

人生中哪段时间最幸福?幸福指数可能会帮你发现。幸福指数要求:对自己每天的生活赋予一个幸福值,幸福值越大表示越幸福。一段时间的幸福指数就是:这段时间的幸福值的和乘以这段时间的幸福值的最小值。幸福指数最大的那段时间,可能就是人生中最幸福的时光。

输入格式:
第1行,1个整数n,, 1≤n≤100000,表示要考察的天数。

第2行,n个整数Hi,用空格分隔,Hi表示第i天的幸福值,0≤n≤1000000。

输出格式:
第1行,1个整数,表示最大幸福指数。

第2行,2个整数l和r,用空格分隔,表示最大幸福指数对应的区间[l,r]。如果有多个这样的区间,输出最长最左区间。

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

7
6 4 5 1 4 5 6
输出样例:
在这里给出相应的输出。例如:

60
1 3

思路

第四题,是一个单调栈问题,我使用了两个栈,分别用来存储数列中某一个数字左边和右边第一个比它小的数字。并且使用了一个数组add,求出到n项(假设此刻为第n项)的和,最后用来相乘,得出题解。

注意!:
1.要将第0项和第n+1项置为负数,避免发生找不到比自己小的数的情况。
2.注意要输出最长最左区间,要设置两个条件约束最长和最左。

代码

#include<iostream>
#include<stack>
using namespace std;
long long ans[100004];
long long add[100004];
long long temp=0;
long long key=0;
long long ll;
long long rr;
long long l[100004],r[100004];
int main(){
stack<int>lsmal;
stack<int>rsmal;
int num;
ios::sync_with_stdio(false);
cin.tie(0);
cin>>num;
ans[0]=ans[num+1]=-1;
for(int i=1;i<=num;++i){
    cin>>ans[i];
    add[i]=add[i-1]+ans[i];
}
lsmal.push(0);
for(int i=1;i<=num;++i){
    while(!lsmal.empty()&&ans[lsmal.top()]>=ans[i]){
        lsmal.pop();
    }
    l[i]=lsmal.top();
    lsmal.push(i);
}
rsmal.push(num+1);
for(int i=num;i>=1;--i){
    while(!rsmal.empty()&&ans[rsmal.top()]>=ans[i]){
        rsmal.pop();
    }
    r[i]=rsmal.top();
    rsmal.push(i);
}
for(int i=1;i<=num;++i){
    temp=(add[r[i]-1]-add[l[i]])*ans[i];
    if(temp>key){
        key=temp;
        ll=l[i]+1;
        rr=r[i]-1;
    }
    else if(temp==key&&rr-ll<r[i]-1-l[i]-1){
        ll=l[i]+1;
        rr=r[i]-1;
    }
    else if(temp==key&&l[i]+1<ll){
        ll=l[i]+1;
        rr=r[i]-1;
    }
}
cout<<key<<"\n"<<ll<<" "<<rr<<"\n";
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值