UVA135 题解:输出矩阵的规律及代码实现

题目大意

按照以下规律输出矩阵。(我调了下空格和换行)

Input:
5

Output:
1  2  3  4  5
1  6  7  8  9
1 10 11 12 13
1 14 15 16 17
1 18 19 20 21

2  6 10 14 18
2  7 11 15 19
2  8 12 16 20
2  9 13 17 21

3  6 11 16 21
3  7 12 17 18
3  8 13 14 19
3  9 10 15 20

4  6 12 14 20
4  7 13 15 21
4  8 10 16 18
4  9 11 17 19

5  6 13 16 19
5  7 10 17 20
5  8 11 14 21
5  9 12 15 18

理性分析

通过找规律,我们发现第一个 'k × k' 的矩阵的规律是每行第一个为 '1',剩下的为 'k + 1' 到 'k^2 - k + 1' 依次按行排列。

接下来的矩阵都是 '(k - 1) × k' 的,第一个数为该矩阵的编号,那我们把第 'i' 个矩阵中每一个元素都给予编号,第 'j' 行第 'o' 列的元素就等于 '(o - 1) × (k - 1) + (((o - 1) × i + j - 1) mod (k - 1)) + 1'。

咳咳,有些繁琐呢。讲一下为什么。

看这一组数据:

2  6 10 14 18
2  7 11 15 19
2  8 12 16 20
2  9 13 17 21

和这一组:

3  6 11 16 21
3  7 12 17 18
3  8 13 14 19
3  9 10 15 20

我们发现排除第一列,变成了这样:

6 10 14 18
7 11 15 19
8 12 16 20
9 13 17 21

和这样:

6 11 16 21
7 12 17 18
8 13 14 19
9 10 15 20

我们发现第二组数据相比于第一组数据(更改后),第一列上移了 '0' 个位置,第二列上移了 '1' 个位置,第三列及 '2' 个,第四列就是 '3' 个。

是不是这回事?也就是循环位移,这种情况可以直接算出某个数的列数和行数,再倒过来一推,就可以知道哪一行哪一列是哪个数了。

即:那我们把第 'i' 个矩阵中每一个元素都给予编号,第 'j' 行第 'o' 列的元素就等于 '(o - 1) × (k - 1) + (((o - 1) × i + j - 1) mod (k - 1)) + 1'。

代码实现

不用讲了吧。。。

code

AC 记录

代码

#include <bits/stdc++.h>
using namespace std;

int k, T, m;
int main()
{
	while (scanf("%d", &k) == 1)
	{
		if (T)
		{
			printf("\n");
		}
		T++;
		if (k == 1)
		{
			printf("1\n");
			continue;
		}
		m = k - 1;
		for (int i = 0; i < k; i++)
		{
			printf("1 ");
			for (int j = 1; j < k; j++)
			{
				printf("%d%c", i * m + j + 1, j == k - 1 ? '\n' : ' '); // UVA 的百年老坑 
			}
		}
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < m; j++)
			{
				printf("%d ", i + 2);
				for (int o = 0; o < m; o++)
				{
					printf("%d%c", (j + o * i) % m + o * m + k + 1, o == m - 1 ? '\n' : ' '); // UVA 的百年老坑 
				}
			}
		}
	}
}
UVA135 题解:输出矩阵的规律及代码实现

原文地址: https://www.cveoy.top/t/topic/qdZ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录