Matrix
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 651 Accepted Submission(s): 276
1 x y: Swap row x and row y (1≤x,y≤n) ;
2 x y: Swap column x and column y (1≤x,y≤m) ;
3 x y: Add y to all elements in row x (1≤x≤n,1≤y≤10,000) ;
4 x y: Add y to all elements in column x (1≤x≤m,1≤y≤10,000) ;
The first line contains three integers n , m and q .
The following n lines describe the matrix M. (1≤Mi,j≤10,000) for all (1≤i≤n,1≤j≤m) .
The following q lines contains three integers a(1≤a≤4) , x and y .
2
3 4 2
1 2 3 4
2 3 4 5
3 4 5 6
1 1 2
3 1 10
2 2 2
1 10
10 1
1 1 2
2 1 2
Sample Output
12 13 14 15
1 2 3 4
3 4 5 6
1 10
10 1
题目大意:
一共有四种操作,分别编号为1、2、3、4.对于每种操作:
1、交换x、y两行。
2、交换x、y两列。
3、在x行上边加上y。
4、在x列上边加上y。
输出全部q个操作之后的M矩阵。
分析:因为n、m都不小,而且q也比较大,所以直接暴力模拟是一定一定一定一定会超时的,所以我们尽量使得操作不是q*n。这里我们先把一个矩阵简单化看成只有一个列的矩阵,对其进行这些个操作,比如我们现在有一个5*1的M矩阵row【5】:
1
2
3
4
5
因为每一行都只有一个元素,所以我们直接暴力模拟一下就能够简单操作起来。比如现在要进行:1 2 3的操作,辣么我们直接写代码为这样:
row【2】=row【3】;row【3】=row【2】即可。这样我们类比到一个5*5的矩阵a【5】【5】,其实也可以这样来操作:
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
当我们操作了row【2】=row【3】,row【3】=row【2】的操作的时候,我们看似是操作了一个一维的一个5*1的矩阵的两个元素的交换,其实我们也就可以看成一个行的交换了,当在输出的时候,我们这样输出数据即可:
for(int i=0;i<m;i++)
{
printf("%d ",a[row[i]][i]);
}
同理我们把这种操作也能够平移到操作列上边,这个时候对于1、2操作的思路就可以构建成这样:
建立一个row【】,建立一个col【】。row【2】=3表示第2行的数据变成了第三行的数据,在输出的时候要输出原来矩阵里边的第三行的数据。col【2】=3表示第二列的数据变成了第三列的数据,在输出的时候要输出原来矩阵里边的第三列数据。
同理我们就可以得到当前行当前列的元素是在原矩阵的哪一个元素。不难理解,可以这样来描述:a【row【i】】【col【j】】表示表示第i行第j列的数据应该输出在原来数据的第row【i】行col【j】列上边的元素。
辣么对于3、4操作其实就更容易操作了,我们不妨将row【i】数组变成row【i】【2】,row【i.】【0】表示row【i】的数据,row【i】【1】表示row【i】这一行的数据上需要加上的数值。这里要注意一点,在操作1、2的时候,注意要将row【】【1】和col【】【1】也进行转移。
这里口述可能说的相对较浅,我们拿出代码对于1、2操作的代码实现:
if(d==1)
{
y--;//y--是因为我开的矩阵是从(0,0)作为左上角开始的
int tmp=row[x][0];
int tmp2=row[x][1];
row[x][0]=row[y][0];//交换行
row[x][1]=row[y][1];//同时不要忘记了交换增加的数值
row[y][1]=tmp2;
row[y][0]=tmp;
}
if(d==2)
{
y--;
int tmp=col[x][0];
int tmp2=col[x][1];
col[x][0]=col[y][0];//交换列
col[x][1]=col[y][1];
col[y][1]=tmp2;
col[y][0]=tmp;
}
对于3、4操作的代码实现:
if(d==3)
{
row[x][1]+=y;
}
if(d==4)
{
col[x][1]+=y;
}
对于这个题的完整的AC代码:
#include<stdio.h>
#include<string.h>
using namespace std;
int a[1212][1212];
int row[1212][2];
int col[1212][2];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
int n,m,q;
scanf("%d%d%d",&n,&m,&q);
for(int i=0; i<n; i++)row[i][0]=i,row[i][1]=0;
for(int i=0; i<m; i++)col[i][0]=i,col[i][1]=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
scanf("%d",&a[i][j]);
}
}
//printf("yes\n");
while(q--)
{
int d,x,y;
scanf("%d%d%d",&d,&x,&y);
x--;
if(d==1)
{
y--;
int tmp=row[x][0];
int tmp2=row[x][1];
row[x][0]=row[y][0];
row[x][1]=row[y][1];
row[y][1]=tmp2;
row[y][0]=tmp;
}
if(d==2)
{
y--;
int tmp=col[x][0];
int tmp2=col[x][1];
col[x][0]=col[y][0];
col[x][1]=col[y][1];
col[y][1]=tmp2;
col[y][0]=tmp;
}
if(d==3)
{
row[x][1]+=y;
}
if(d==4)
{
col[x][1]+=y;
}
/*
for(int i=0; i<n; i++)
{
int f=0;
for(int j=0; j<m; j++)
{
if(f!=0)
printf(" %d",a[row[i][0]][col[j][0]]+row[i][1]+col[j][1]);
else printf("%d",a[row[i][0]][col[j][0]]+row[i][1]+col[j][1]);
f++;
}
printf("\n");
}*/
}
for(int i=0; i<n; i++)
{
int f=0;
for(int j=0; j<m; j++)
{
if(f!=0)
printf(" %d",a[row[i][0]][col[j][0]]+row[i][1]+col[j][1]);
else printf("%d",a[row[i][0]][col[j][0]]+row[i][1]+col[j][1]);
f++;
}
printf("\n");
}
}
}