问题 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;
}