数据结构作业6

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:785解决:632

返回比赛提交提交记录侧边提交

题目描述

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

int main() {

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

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

    return 0;

}

输入

输出

计算结果

样例输入 复制


样例输出 复制

the result is 6

提示

代码框架如下所示,请补充完整,调试通过后,注释掉main函数代码再提交

#include <stdarg.h>

#include <stdio.h>

int sum(int cnt, ...) {

    // please write your code

}

int main() {

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

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

    return 0;

}

下面的示例程序演示了函数参数不定情况下的处理代码
 

 

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:pengsw

提交:1392解决:1032

返回比赛提交提交记录侧边提交

题目描述

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

 

输入

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

输出

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

样例输入 复制

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

样例输出 复制

6
5

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:883解决:661

返回比赛提交提交记录侧边提交

题目描述

输入一个稀疏矩阵,输出其类型。类型包括:
上三角:对角线及其右上方的元素非0,其它元素为0
下三角:对角线及其左下方的元素非0,其它元素为0
对称:沿对角线对称的元素非0且相等
空矩阵:所有元素都为0
其它为普通矩阵

输入

输入包括多组数据
每组数据的第一行为小于100的正整数m和n,分别代表矩阵的行数和列数,接下来跟着m行,每行是空格隔开的n个整数

输出

对输入的每组数据,输出矩阵类型对应的汉语拼音。

样例输入 复制

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

样例输出 复制

shangsanjiao
xiasanjiao
duichen
kong
putong
putong

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:1158解决:722

返回比赛提交提交记录侧边提交

题目描述

大部分元素是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
试编程读入一稀疏矩阵,转换成简记形式,并输出。
本题为附加代码模式,main函数代码会自动补在同学们提交的代码后面,具体如下:

int main()

{

    // freopen("/config/workspace/answer/test.in","r",stdin);

    int *matrix, m, n;

    cin >> m;

    cin >> n;

    matrix = new int[m*n];

    for (int i = 0; i < m*n; i++)

        cin >> matrix[i];

    TriTable T;

    CreateTriTable(T, matrix, m, n);

    PrintTriTable(T);

    DestroyTriTable(T);

    delete []matrix;

    return 0;

}

输入

首先有一行两个整数n和m,表示矩阵的行数和列数。 1<=n,m<=100
接下来的n行,每行有m个数,表示该矩阵。

输出

按题目要求输出矩阵的简记形式。

样例输入 复制

3 5
0 0 0 0 5
0 0 4 0 0
1 0 0 0 1

样例输出 复制

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

提示

代码框架如下图所示:

 

 

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:2897解决:1311

返回比赛提交提交记录侧边提交

题目描述

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

输入

输入包括一组测试数据,对应三元组表示的稀疏矩阵。
第一行为矩阵行数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

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:liuyong

提交:802解决:698

返回比赛提交提交记录侧边提交

题目描述

给定一个三元组法表示的稀疏矩阵,计算每行非零元个数,行向量,每列非零元个数,列向量并输出。

输入

输入第一行为稀疏矩阵的行数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

 

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:2011014323

提交:3678解决:1705

返回比赛提交提交记录侧边提交

题目描述

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

矩阵转置就是将矩阵行和列上的元素对换。

现在就请你对一个稀疏矩阵进行转置。以下是稀疏矩阵转置的算法描述:

图:稀疏矩阵转置的算法描述

输入

输入的第一行是两个整数r和c(r*c <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r行,每行有c个整数,表示这个稀疏矩阵的各个元素。

输出

输出c行,每行有r个整数,每个整数后跟一个空格。该结果为输入稀疏矩阵的转置矩阵。

样例输入 复制

6 7
0 12 9 0 0 0 0
0 0 0 0 0 0 0
-3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 -7 0 0 0

样例输出 复制

0 0 -3 0 0 15 
12 0 0 0 18 0 
9 0 0 24 0 0 
0 0 0 0 0 -7 
0 0 0 0 0 0 
0 0 14 0 0 0 
0 0 0 0 0 0 

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

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:2011014323

提交:3687解决:2060

返回比赛提交提交记录侧边提交

题目描述

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

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

现在就请你实现一个快速的对稀疏矩阵进行转置的算法。以下是稀疏矩阵快速转置的算法描述:

输入

输入的第一行是两个整数r和c(r<300, c<300, r*c <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r行,每行有c个整数,用空格隔开,表示这个稀疏矩阵的各个元素。

输出

输出为读入的稀疏矩阵的转置矩阵。输出共有c行,每行有r个整数,每个整数后输出一个空格。请注意行尾输出换行。

样例输入 复制

6 7
0 12 9 0 0 0 0
0 0 0 0 0 0 0
-3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 -7 0 0 0

样例输出 复制

0 0 -3 0 0 15 
12 0 0 0 18 0 
9 0 0 24 0 0 
0 0 0 0 0 -7 
0 0 0 0 0 0 
0 0 14 0 0 0 
0 0 0 0 0 0 

提示

*** 提示已隐藏,点击此处可显示 ***

收起提示[-]

提示: 这个算法仅比算法5.1多用了两个辅助向量。对于这个算法的时间复杂度,不难发现算法中有4个并列的单循环,循环次数分别为nu和tu,因而总的时间复杂度为O(nu+tu)。而当稀疏矩阵的非零元个数tu和mu×nu的数量级相同时,其时间复杂度为O(mu×nu),与经典算法的时间复杂度相同。 请注意理解为什么转置算法中,以列从小到大来进行转置。实际上只需一个循环就能够完成转置而不需将列从小到大来处理,转置后的矩阵虽然内容正确,但元素的顺序却发生了变化,以至于在后续的各种处理操作中会增加复杂度。而在本题中,如果不按照列从小到大的顺序处理将导致输出困难,大大增加输出的复杂度。 总结: 稀疏矩阵是矩阵应用中很重要的一部分,由于其元素稀疏的特殊性质,我们可以得到比传统矩阵算法更快速的特殊算法。这也将会在本章后面的题目中得到体现。

问题 BC: 算法5-3:带行向量的稀疏矩阵相乘(附加代码模式)

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:16解决:152

返回比赛提交提交记录侧边提交

题目描述

请使用带行向量的三元组法存储的稀疏矩阵,实现矩阵乘法。
本题为附加代码模式,以下代码会自动附加在提交的代码后面,请同学们注释之后提交

// 两个三元组法表示的矩阵相乘

TriMatrix Mul(const TriMatrix& M1, const TriMatrix& M2){

    TriMatrix M;

    M.mu = M1.mu;  M.nu = M2.nu; M.tu = 0;

    for(int i=0;i<M1.tu;i++){

        int c = M1.data[i].c;

        for(int j=M2.rpos[c];j<M2.rpos[c]+M2.rsum[c];j++){

            AddNode(M,M1.data[i].r,M2.data[j].c,M1.data[i].v * M2.data[j].v);

        }

    }

    return M;

}

int main(){

    // freopen("/config/workspace/answer/test.in","r",stdin);

    // freopen("/config/workspace/answer/test.out","w",stdout);

    TriMatrix M1, M2;

    InputMatrix(M1);

    InputMatrix(M2);

    CalcRPosMatrix(M1);

    CalcRPosMatrix(M2);

    // PrintMatrix(M1);

    // PrintMatrix(M2);

    TriMatrix M = Mul(M1,M2);

    CalcRPosMatrix(M);

    // PrintMatrix(M);

    PrintMatrixArray(M);

    return 0;

}

输入

输入的第一行是两个整数r1和c1(r1<200, c1<200, r1*c1 <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r1行,每行有c1个整数,用空格隔开,表示第一个稀疏矩阵的各个元素。 之后的一行有两个整数r2和c2(c1=r2<200, c2<200, r2*c2 <= 12500),分别表示一个包含很多0的稀疏矩阵的行数和列数。接下来有r2行,每行有c2个整数,用空格隔开,表示第二个稀疏矩阵的各个元素。

输出

输出两个矩阵的乘积。输出共有r1行,每行有c2个整数,每个整数后输出一个空格。请注意行尾输出换行。

样例输入 复制

4 5
0 0 0 69 78
0 0 5 0 0
0 0 0 0 0
0 91 2 0 82
5 6
0 18 0 0 0 0
0 0 67 0 0 0
0 0 0 0 0 41
0 0 47 62 0 0
0 0 0 0 0 35

样例输出 复制

0 0 3243 4278 0 2730 
0 0 0 0 0 205 
0 0 0 0 0 0 
0 0 6097 0 0 2952 

提示

(1)题目用vector存储行向量,非零元数据,有关vector的使用方法,请通过搜索引擎查找资料,本题用到的两个vector基本用法如下:
1、在vector后面追加一个元素  

        M.data.push_back({r,c,v});

2、在vector中间index下标所在位置插入一个元素

        vector<TriNode>::iterator it = M.data.begin();

        for(int i=0;i<index;i++) ++it;

        M.data.insert(it,{r,c,v});

(2)本题的代码框架如下,请同学根据注释完成部分函数的代码

#include <iostream>

#include <cstdio>

#include <vector>

using namespace std;

// 三元组结构体

struct TriNode{

    // 行,列,值

    int r,c,v;

};

// 输出单个非零元

void PrintTriNode(const TriNode& T){

    cout << T.r << " " << T.c << " " << T.v << endl;

}

// 稀疏矩阵

struct TriMatrix{

    // 行数,列数,非零元个数

    int mu,nu,tu;

    vector<TriNode> data; // 三元组法表示的非零元

    vector<int> rsum;  // 每行非零元个数

    vector<int> rpos;  // 行向量

};

void InputMatrix(TriMatrix& M){

    cin >> M.mu >> M.nu;

    M.tu = 0;

    for(int i=0;i<M.mu;i++){

        for(int j=0;j<M.nu;j++){

            int t; cin >> t;

            if(t != 0){

                M.data.push_back({i,j,t});

                M.tu++;

            }

        }

    }

}

// 计算三元组法表示的稀疏矩阵的每行非零元个数和行向量

void CalcRPosMatrix(TriMatrix& M){

    // 第一步:计算每行非零元个数

    // 第二步:计算行向量

    // 请同学们完成这个函数的功能

}

// 输出三元组法表示的稀疏矩阵,用于辅助调试

void PrintMatrix(const TriMatrix& M){

    cout << "================================================" << endl;

    cout << "mu=" << M.mu << ",nu=" << M.nu << ",tu=" << M.tu << endl;

    for(int i=0;i<M.tu;i++){

        PrintTriNode(M.data[i]);

    }

    cout << "rsum:";

    for(int i=0;i<M.mu;i++) cout << M.rsum[i] << " ";

    cout << endl;

    cout << "rpos:";

    for(int i=0;i<M.mu;i++) cout << M.rpos[i] << " ";

    cout << endl;

    cout << "================================================" << endl;

}

// 用二维数组的形式输出三元组法表示的稀疏矩阵

void PrintMatrixArray(const TriMatrix& M){

    int array[M.mu][M.nu] = {0};

    for(int i=0;i<M.mu;i++){

        for(int j=0;j<M.nu;j++){

            array[i][j] = 0;

        }

    }

    for(int i=0;i<M.tu;i++){

        array[M.data[i].r][M.data[i].c] = M.data[i].v;

    }

    for(int i=0;i<M.mu;i++){

        for(int j=0;j<M.nu;j++){

            cout << array[i][j] << " ";

        }

        cout << endl;

    }

}

// 三元组法表示的稀疏矩阵,添加非零元

void AddNode(TriMatrix& M, int r, int c, int v){

    // 1、如果已存在行列相同的节点,追加值

    // 2、否则,将该非零元按行优先的顺序找到合适的位置,插入节点

    // 请同学们完成这个函数的功能

}


 

// !!!!!以下代码会自动附加,请同学注释之后提交

// 两个三元组法表示的矩阵相乘

TriMatrix Mul(const TriMatrix& M1, const TriMatrix& M2){

    TriMatrix M;

    M.mu = M1.mu;  M.nu = M2.nu; M.tu = 0;

    for(int i=0;i<M1.tu;i++){

        int c = M1.data[i].c;

        for(int j=M2.rpos[c];j<M2.rpos[c]+M2.rsum[c];j++){

            AddNode(M,M1.data[i].r,M2.data[j].c,M1.data[i].v * M2.data[j].v);

        }

    }

    return M;

}

int main(){

    // freopen("/config/workspace/answer/test.in","r",stdin);

    // freopen("/config/workspace/answer/test.out","w",stdout);

    TriMatrix M1, M2;

    InputMatrix(M1);

    InputMatrix(M2);

    CalcRPosMatrix(M1);

    CalcRPosMatrix(M2);

    // PrintMatrix(M1);

    // PrintMatrix(M2);

    TriMatrix M = Mul(M1,M2);

    CalcRPosMatrix(M);

    // PrintMatrix(M);

    PrintMatrixArray(M);

    return 0;

}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值