百花2022年计算机类数据结构作业6

问题 A: 函数可变参数练习-附加代码模式

C和C++语言都支持在函数中使用数量不定的参数列表进行运算。本题使用附加代码模式,用一个简单的求和任务,让同学们练习可变参数的函数语法。
main函数代码如下,会自动附加在同学们提交的代码后面。

int main() {

    int result = sum(3, 1, 2, 3);

    printf("the result is %d\n", result);

    return 0;

}

answer

#include<bits/stdc++.h>
using namespace std;
int sum(int cnt,...){
    int sums=0;
    va_list ap;
    va_start(ap,cnt);
    for(int i=0;i<cnt;i++){
        int arg=va_arg(ap,int);
        sums+=arg;
    }
    va_end(ap);
    return sums;
}
/*int main()
{
    int t=sum(3,1,2,3);
    cout<<t;
    return 0;
}*/

问题 B: 多维下标向一维下标的换算

题目描述

多维数组的元素标识通常是用多维下标(i0, i1, i2, .., in-1),而多维数组以顺序方式存储在内存中,内存的地址空间是一维的,要操作多维数组就需要计算从多维下标向一维下标的换算。

输入格式

输入的每一行为一个测试用例。
每一行由一组非负整数组成,第一个数是多维数组的维数n(2~11),从第二个数开始的n个数是从高维到低维每一维的维长(1~20),接着的n个数是一个n维下标。下标起始从0开始。

输出格式

对每一个测试样例,计算给定多维下标按行优向顺序对应的一维下标,并输出这个一维下标的值。每个测试样例输出一行。

#include<bits/stdc++.h>
using namespace std;
 
int main()
{
    int n;
    while(cin>>n){
        int a[105],b[105];
        //cin>>a[0];
        for(int i=0;i<n;i++){
            cin>>a[i];
            //if(i)
             //   a[i]+=a[i-1];
        }
        for(int i=0;i<n;i++){
            cin>>b[i];
            //if(i)
            //    b[i]+=b[i-1];
        }
        int sum=0;
        for(int i=0;i<n;i++){
            int t=b[i];
            for(int j=i+1;j<n;j++) t*=a[j];
            sum+=t;
        }
        cout<<sum<<endl;
    }
    return 0;
}

问题 C: 稀疏矩阵类型判断

题目描述

输入一个稀疏矩阵,输出其类型。类型包括:

上三角:对角线及其右上方的元素非0,其它元素为0

下三角:对角线及其左下方的元素非0,其它元素为0

对称:沿对角线对称的元素非0且相等

空矩阵:所有元素都为0

其它为普通矩阵

#include<bits/stdc++.h>
using namespace std;
int a[105][105];
int check(int m,int n){
    if(m==0&&n==0) return 0;
 
       bool f5=1;
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(a[i][j]){
                f5=0;
                break;
            } 
        }
    }
    if(f5) return 5;
    bool f1=1;
    for(int i=1;i<m;i++){
        for(int j=0;j<i;j++){
            if(a[i][j]){
                f1=0;
                break;
            } 
        }
    }
    if(f1) return 1;
    bool f2=1;
    for(int i=0;i<m-1;i++){
        for(int j=i+1;j<n;j++){
            if(a[i][j]){
                f2=0;
                break;
            } 
        }
    }
    if(f2) return 2;
    if(m==n){
        bool f3=1,f4=1;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if((i!=j&&a[i][j]==0)||(a[i][j]!=a[j][i])){
                    f3=0;
                    break;
                } 
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if((i!=j&&a[i][j]==0)||(a[i][j]!=a[n+1-j][n+1-i])){
                    f4=0;
                    break;
                } 
            }
        }
        if(f3||f4)
            return 3;
    }
  
    return 6;
}
int main()
{
    int m,n;
    while(cin>>m>>n){
        for(int i=0;i<m;i++)
        for(int j=0;j<n;j++) cin>>a[i][j];
        if(m!=n) cout<<"putong"<<endl;
        else{
            int t=check(m,n);
            if(t==1) cout<<"shangsanjiao"<<endl;
            else if(t==2) cout<<"xiasanjiao"<<endl;
            else if(t==3) cout<<"duichen"<<endl;
            else if(t==5) cout<<"kong"<<endl;
            else cout<<"putong"<<endl;
        }
    }
 
    return 0;
}

问题 D: 稀疏矩阵转换成简记形式-附加代码模式

大部分元素是0的矩阵称为稀疏矩阵,假设有k个非0元素,则可把稀疏矩阵用k*3的矩阵简记之,其中第一列是行号,第二列是列号,第三列是该行、该列下的非元素的值。如:
0 0 0 5
0 2 0 0
0 1 0 0
可以简记成:
1 4 5
2 2 2
3 2 1
试编程读入一稀疏矩阵,转换成简记形式,并输出。

不会,直接改函数-_-|||

#include<bits/stdc++.h>
using namespace std;
//#define vector<int> TriTable
typedef vector<int> TriTable;
/*struct TriNode{
    int row,col;
    int data;
};
 
struct TriTable{
    TriNode *datas;
    int mu,nu,tu;
};*/
vector<int> q;
void CreateTriTable(TriTable &T,int maxtrix[],int m,int n){
    /*T.mu=m,T.nu=n;int num=0;
    for(int i=0;i<m*n;i++)
        if(maxtrix[i]){
            T.datas[num].row=i/m;
            T.datas[num].col=i%n;
            T.datas[num].data=maxtrix[i];
            num++;
        }
    T.tu=num;*/
    for(int i=0;i<m*n;i++)
        T.push_back(maxtrix[i]);    
    q.push_back(m);
    q.push_back(n);    
}
int DestroyTriTable(TriTable &t){
    return 0;
}
void PrintTriTable(TriTable &T){
    int k=0;
    int  m=q.back();q.pop_back();
    int n=q.back();
    for(auto i:T){
        if(i!=0)
            cout<<k/m+1<<" "<<k%m+1<<" "<<i<<endl;
        k++;    
    }
}
/*int main()
{
    int *maxtrix,m,n;
    cin>>m>>n;
    maxtrix=new int[n*m];
    for(int i=0;i<m*n;i++) cin>>maxtrix[i];
    TriTable T;
    CreateTriTable(T,maxtrix,m,n);
    PrintTriTable(T);
    DestroyTriTable(T);
    delete []maxtrix;
    return 0;
}*/

问题 E: 根据三元组输出稀疏矩阵

题目描述

给定三元组表示的稀疏矩阵,输出对应的矩阵

输入格式

输入包括一组测试数据,对应三元组表示的稀疏矩阵。
第一行为矩阵行数m,第二行为矩阵列数n,第三行为非零元个数t。 m,n都为小于100的正整数,t为小于10000的非负整数。
接下来t行为t个非零元的行、列、值,都是整数

输出格式

输出对应的稀疏矩阵

输入样例 复制

m=3
n=2
t=1
1 1 5

输出样例 复制

0 0
0 5
0 0

 输入坑了点.

#include<bits/stdc++.h>
using namespace std;
int a[105][105]={0};
int main()
{
    int m,n,t;
    int b[5]={0};
    for(int i=0;i<3;i++){
        string s;
        cin>>s;
        for(int j=2;j<s.length();j++)
            b[i]=b[i]*10+int(s[j]-'0');
    }
    //for(int i=0;i<3;i++) cout<<b[i]<<endl;
    m=b[0],n=b[1],t=b[2];
    for(int i=0;i<t;i++){
        int x,y,z;
        cin>>x>>y>>z;
        a[x][y]=z;
    }
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++) cout<<a[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

问题 F: 三元组法表示的稀疏矩阵,计算每行非零元个数,行索引,每列非零元个数,列索引

题目描述

给定一个三元组法表示的稀疏矩阵,计算每行非零元个数,行索引,每列非零元个数,列索引并输出。其中行索引,指的是该行起始位置在稀疏矩阵的值向量中的索引,同理,列索引,指的是该列起始位置在稀疏矩阵的值向量中的索引。

输入格式

输入第一行为稀疏矩阵的行数mu,第二行为稀疏矩阵的列数nu,第三行为稀疏矩阵的非零元个数tu,其中mu,nu,tu都是小于100的正整数
接下来tu行,每行包括空格分隔的3个整数,分别代表每个非零元的行、列、值。

输出格式

输出四个向量,分别是每行非零元个数,行索引,每列非零元个数,列索引。

输入样例 复制

5
6
7
0 1 2
0 4 5
1 3 7
2 3 11
2 4 5
2 5 2
4 4 8

输出样例 复制

rowSum: 2 1 3 0 1
rowPos: 0 2 3 6 6
colSum: 0 1 0 2 3 1
colPos: 0 0 1 1 3 6

 

#include<bits/stdc++.h>
using namespace std;
int a[105][105]={0};
int row[105]={0},col[105]={0};
int rowpos[105]={0},colpos[105]={0};
int main()
{
    int m,n,t;
    cin>>m>>n>>t;
    for(int i=0;i<t;i++){
        int x,y,z;
        cin>>x>>y>>z;
        a[x][y]=z;
    }
    /*for(int i=0;i<m;i++){
        for(int j=0;j<n;j++) cout<<a[i][j]<<" ";
        cout<<endl;
    }*/
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            if(a[i][j]) row[i]++;
        }
    }
    for(int j=0;j<n;j++){
        for(int i=0;i<m;i++){
            if(a[i][j]) col[j]++;
        }
    }
    cout<<"rowSum: ";
    for(int i=0;i<m;i++) cout<<row[i]<<" ";
    cout<<endl;
    cout<<"rowPos: 0 ";
    for(int i=1;i<m;i++){
         
        cout<<row[i-1]<<" ";
        row[i]+=row[i-1];
    }
    cout<<endl;
 
 
    cout<<"colSum: ";
    for(int i=0;i<n;i++) cout<<col[i]<<" ";
    cout<<endl;
    cout<<"colPos: 0 ";
    for(int i=1;i<n;i++){
        cout<<col[i-1]<<" ";
        col[i]+=col[i-1];
    }
    return 0;
}

问题 G: 算法5-1:稀疏矩阵转置

稀疏矩阵的存储不宜用二维数组存储每个元素,那样的话会浪费很多的存储空间。所以可以使用一个一维数组存储其中的非零元素。这个一维数组的元素类型是一个三元组,由非零元素在该稀疏矩阵中的位置(行号和列号对)以及该元组的值构成。矩阵转置就是将矩阵行和列上的元素对换。

#include<bits/stdc++.h>
using namespace std;
int a[1005][1005]={0};
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) cin>>a[i][j];
    for(int j=0;j<m;j++){
        for(int i=0;i<n;i++)
            cout<<a[i][j]<<" ";
        cout<<endl;    
    }
 
    return 0;
}

问题 H: 算法5-2:稀疏矩阵快速转置

稀疏矩阵的存储不宜用二维数组存储每个元素,那样的话会浪费很多的存储空间。所以可以使用一个一维数组存储其中的非零元素。这个一维数组的元素类型是一个三元组,由非零元素在该稀疏矩阵中的位置(行号和列号对)以及该元组的值构成。

而矩阵转置就是将矩阵行和列上的元素对换。参考算法5.1中的具体做法,令mu和nu分别代表稀疏矩阵的行数和列数,不难发现其时间复杂度为O(mu×nu)。而当非零元的个数tu与mu×nu同数量级时,算法5.1的时间复杂度将上升至O(mu×nu2)。因此,需要采用快速的稀疏矩阵转置算法。

不会,直接简单粗暴。

#include<bits/stdc++.h>
using namespace std;
int a[1005][1005]={0};
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) cin>>a[i][j];
    for(int j=0;j<m;j++){
        for(int i=0;i<n;i++)
            cout<<a[i][j]<<" ";
        cout<<endl;    
    }
 
    return 0;
}

问题 I: 算法5-3:行逻辑链接的矩阵乘法

请使用行逻辑链接的顺序表实现两个稀疏矩阵的乘法。

不会,还是简单粗暴法。

#include<bits/stdc++.h>
using namespace std;
int a[1005][1005]={0};
int b[1005][1005]={0};
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) cin>>a[i][j];
    int k;
    cin>>m>>k;
    for(int i=0;i<m;i++)
        for(int j=0;j<k;j++) cin>>b[i][j];
    for(int i=0;i<n;i++){
        for(int j=0;j<k;j++){
            int s=0;
            for(int t=0;t<m;t++){
                s+=a[i][t]*b[t][j];
            }
            cout<<s<<" ";
        }
        cout<<endl;
    }    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值