PAT甲级 A1105

PAT甲级 A1105

题目详情

1105 Spiral Matrix (25分)
This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasing order. A spiral matrix is filled in from the first element at the upper-left corner, then move in a clockwise spiral. The matrix has m rows and n columns, where m and n satisfy the following: m×n must be equal to N; m≥n; and m−n is the minimum of all the possible values.

Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N. Then the next line contains N positive integers to be filled into the spiral matrix. All the numbers are no more than 10
​4
​​ . The numbers in a line are separated by spaces.

Output Specification:
For each test case, output the resulting matrix in m lines, each contains n numbers. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.

Sample Input:
12
37 76 20 98 76 42 53 95 60 81 58 93
Sample Output:
98 95 93
42 37 81
53 20 76
58 60 76

解题思路

这道题涉及到公因数的分解以及旋转矩阵的生成。本题的具体流程如下:
1.根据查找公因数的方法找出次数相差最小的商,大的存储为m,小的存储为n
2.建立矩阵,将数据实用sort函数从小到大排序
3.开始旋转,旋转时建立一个方向变量表示此时是向上填充,向右填充,向左填充或向下填充。判断边界条件使得向上填充变为向右填充,向右填充变为向下填充,向下填充变为向左填充,向左填充变为向上填充
以下为AC代码

#include<algorithm>
#include<iostream>
#include<vector>
#include<cmath>
#include<iomanip>
#include<map>
#include<queue>
#include<string>
using namespace std;
int N;
int INF = 1e9;
const int maxN = 200;
int ma[maxN][maxN];
int ques[10010];
int findmn(int N) {
	int minst = INF;
	int m = N;
	for (int i = 2; i <= sqrt(N); i++) {
		if (N % i == 0) {
			int ca = max(i, N / i) - min(i, N / i);
			if (ca < minst) {
				minst = ca;
				m = max(i, N / i);
			}
		}
	}
	return m;
}
bool cmp(int a, int b) {
	return a > b;
}
int main() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		scanf_s("%d", &ques[i]);
	}
	int m, n;
	m = findmn(N);
	n = N / m;
	sort(ques, ques + N,cmp);
	string direction = "right";
	fill(ma[0], ma[0] + 200 * 200, INF);
	int cn = 0; int ln = 0;
	for (int i = 0; i < N; i++) {;
		ma[cn][ln] = ques[i];
		if (direction == "right") {
			if (ln == n - 1) {
				cn = cn + 1;
				direction = "down";
			}
			else if (ma[cn][ln + 1] != INF) {
				cn = cn + 1;
				direction = "down";
			}
			else {
				ln = ln + 1;
			}
			continue;
		}
		else if (direction == "left") {
			if (ln == 0) {
				cn = cn - 1;
				direction = "up";
			}
			else if (ma[cn][ln - 1] != INF) {
				cn = cn - 1;
				direction = "up";
			}
			else {
				ln = ln - 1;
			}
			continue;
		}
		else if (direction == "up") {
			if (cn == 0) {
				ln = ln + 1;
				direction = "right";
			}
			else if (ma[cn-1][ln] != INF) {
				ln = ln + 1;
				direction = "right";
			}
			else {
				cn=cn-1;
			}
			continue;
		}
		else {
			if (cn == m-1) {
				ln = ln - 1;
				direction = "left";
			}
			else if (ma[cn + 1][ln] != INF) {
				ln = ln - 1;
				direction = "left";
			}
			else {
				cn = cn + 1;
			}
			continue;
		}
	}
	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n; j++) {
			if (j == 0) {
				cout << ma[i][j];
			}
			else {
				cout <<" "<<ma[i][j];
			}
		}
		cout << '\n';
	}
	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值