您的位置:首页 > 其它

hdu 5671 Matrix【思维】

2016-04-25 15:56 302 查看


Matrix

Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 651    Accepted Submission(s): 276


Problem Description

There is a matrix M that
has n rows
and m columns (1≤n≤1000,1≤m≤1000).Then
we perform q(1≤q≤100,000) operations:

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);

 

Input

There are multiple test cases. The first line of input contains an integer T(1≤T≤20) indicating
the number of test cases. For each test case:

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.

 

Output

For each test case, output the matrix M after
all q operations.

Sample Input

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");
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 5671 杭电 5671