十字爆破——预处理计算矩阵行列和

链接:https://ac.nowcoder.com/acm/contest/5600/I
来源:牛客网

题目描述
牛牛在玩一个游戏:
一共有n行m列共nm个方格,每个方格中有一个整数。
牛牛选择一个方格,可以得到和这个方格同行、同列的所有数之和的得分。
例如:对于一个2
2的方格:
1 2
3 4
牛牛选择每个方格的得分如下:
6 7
8 9
因为1+2+3=6,1+2+4=7,1+3+4=8,2+3+4=9。
现在牛牛想知道下一步选择每个格子的得分情况,你可以帮帮他吗?
输入描述:

第一行有两个正整数 和 ,代表方格的行数和列数。
接下来的 行,每行有 个数 aija_{ij}aij​,代表每个方格中的整数。

输出描述:

输出 行 列整数,分别代表选择每个位置方格的得分情况。

示例1
输入
复制

2 2
1 2
3 4

输出
复制

6 7
8 9

备注:

本题输入和输出数据量较大,尽量使用scanf或更快的IO方式~

本题矩阵的行列m,n是不确定的,所以无法直接开一个非常大的数组。有两个解决办法:
1.使用new动态分配内存,按照每次输入的m,n创建矩阵。
2.对输入的数据预处理,利用三个数组分别记录输入的数据,行数据之和,列数据之和。
处理细节:
(1)将a[i][j] 表示成a[i * m + j]
(2)利用i / m 表示当前行数(n * m的矩阵每行都有m个数),i % m表示当前列数(模的计数性质)

代码实现:

#include 
using namespace std;
long long typedef ll;

ll a[1000010], sl[1000010], sr[1000010]; 

int main()
{
	ll n, m;
	cin >> n >> m;
	for (ll i = 0; i < n * m; i++) cin >> a[i];
	for (ll i = 0; i < n * m; i++)
	{
		sl[i / m] += a[i];
		sr[i % m] += a[i];
	}
	for (ll i = 0; i < n * m; i++)
	{
		cout << sl[i / m] + sr[i % m] - a[i] << ' ';
		if (i % m == m - 1) cout << endl;
	}
	return 0;
}

你可能感兴趣的:(算法,题解,c++)