矩阵重塑(其一)
题目描述
矩阵的重塑操作可以具体定义为以下步骤:
设原矩阵为 MM,其维度为 n×mn×m,即有 nn 行和 mm 列。新矩阵为 M′M′,其维度为 p×qp×q。重塑操作要满足 n×m=p×qn×m=p×q,这保证了元素的总数不变。
-
线性化原矩阵:按照行优先的顺序,将原矩阵 MM 的元素转换成一个长度为 n×mn×m 的一维数组 AA。这意味着你先读取 MM 的第 00 行元素,然后是第 11 行,依此类推,直到最后一行。
-
填充新矩阵:使用一维数组 AA 中的元素按照行优先的顺序填充新矩阵 M′M′。首先填充 M′M′ 的第 00 行,直到该行有 qq 个元素,然后继续填充第 11 行,直到所有 pp 行都被填满。
给定原矩阵中的一个元素的位置 (i,j)(i,j)(0≤i<n0≤i<n 且 0≤j<m0≤j<m),我们可以找到这个元素在被线性化后的一维数组 AA 中的位置 kk(0≤k<n×m0≤k<n×m),然后确定它在新矩阵 M′M′ 中的位置 (i′,j′)(i′,j′)(0≤i′<p0≤i′<p 且 0≤j<q0≤j<q)。它们之间满足如下数学关系:i×m+j=k=i′×q+j′i×m+j=k=i′×q+j′
给定 n×mn×m 的矩阵 MM 和目标形状 pp、qq,试将 MM 重塑为 p×qp×q 的矩阵 M′M′。
输入格式
从标准输入读入数据。
输入共 n+1n+1 行。
输入的第一行包含四个正整数 nn、mm 和 pp、qq。
接下来依次输入原矩阵 MM 的第 00 到第 n−1n−1 行,每行包含 mm 个整数,按列下标从 00 到 m−1m−1 的顺序依次给出。
输出格式
输出到标准输出。
输出共 pp 行,每行 qq 个整数,表示重塑后的矩阵 M′M′。输出格式与输入相同,即依次输出 M′M′ 的第 00 行到第 p−1p−1 行;行内按列下标从 00 到 q−1q−1 的顺序输出,且两个整数间仅用一个空格分隔。
样例1输入
2 3 3 2
1 2 3
4 5 6
样例1输出
1 2
3 4
5 6
样例2输入
2 2 1 4
6 6
6 6
样例2输出
6 6 6 6
子任务
全部的测试数据满足:
-
nn、mm 和 pp、qq 均为正整数且 n×m=p×q≤104n×m=p×q≤104;
-
输入矩阵中每个元素的绝对值不超过 10001000。
#include<iostream>
using namespace std;
const int MAXN = 1e4+10;
int n,m,p,q;
int k[MAXN];
int main()
{
cin>>n>>m>>p>>q;
int len=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int x;
cin>>k[len++];
}
}
len=1;
for(int i=1;i<=p;i++)
{
for(int j=1;j<=q;j++)
{
cout<<k[len++];
if(j==q)cout<<endl;
else cout<<" ";
}
}
return 0;
}
矩阵重塑(其二)
题目描述
给定 n×mn×m 的矩阵 MM,试编写程序支持以下查询和操作:
-
重塑操作 pp、qq:将当前矩阵重塑为 p×qp×q 的形状(重塑的具体定义见上一题);
-
转置操作:将当前矩阵转置;
-
元素查询 ii、jj:查询当前矩阵第 ii 行 jj 列的元素(0≤i<n0≤i<n 且 0≤j<m0≤j<m)。
依次给出 tt 个上述查询或操作,计算其中每个查询的结果。
输入格式
从标准输入读入数据。
输入共 n+t+1n+t+1 行。
输入的第一行包含三个正整数 nn、mm 和 tt。
接下来依次输入初始矩阵 MM 的第 00 到第 n−1n−1 行,每行包含 mm 个整数,按列下标从 00 到 m−1m−1 的顺序依次给出。
接下来输入 tt 行,每行包含形如 op a b
的三个整数,依次给出每个查询或操作。具体输入格式如下:
-
重塑操作:
1 p q
-
转置操作:
2 0 0
-
元素查询:
3 i j
输出格式
输出到标准输出。
每个查询操作输出一行,仅包含一个整数表示查询结果。
样例1输入
3 2 3
1 2
3 4
5 6
3 0 1
1 2 3
3 1 2
样例1输出
2
6
样例2输入
3 2 5
1 2
3 4
5 6
3 1 0
2 0 0
3 1 0
1 3 2
3 1 0
样例2输出
3
2
5
初始矩阵: [123456]135246, (1,0)(1,0) 位置元素为 33;
转置后: [135246][123456], (1,0)(1,0) 位置元素为 22;
重塑后: [135246]154326, (1,0)(1,0) 位置元素为 55。
子任务
8080 的测试数据满足:
- t≤100t≤100;
全部的测试数据满足:
-
t≤105t≤105 且其中转置操作的次数不超过 100100;
-
nn、mm 和所有重塑操作中的 pp、qq 均为正整数且 n×m=p×q≤104n×m=p×q≤104;
-
输入矩阵中每个元素的绝对值不超过 10001000。
#include<iostream>
using namespace std;
const int MAXN = 1e4+10;
int n,m,t;
int k[MAXN];
int temp[MAXN];
int main()
{
cin>>n>>m>>t;
for(int i=0;i<n*m;i++)
{
cin>>k[i];
temp[i]=k[i];
}
while(t--)
{
int op,a,b;
cin>>op>>a>>b;
switch (op)
{
case 1:
n=a,m=b;
break;
case 2:
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
k[j*n+i]=temp[i*m+j];
}
}
for(int i=0;i<n*m;i++)
{
temp[i]=k[i];
}
swap(n,m);
break;
case 3:cout<<k[a*m+b]<<endl;
break;
default:
break;
}
}
return 0;
}