1105 Spiral Matrix (25分)

题目链接:1105 Spiral Matrix (25分)

题意:

给定正整数N,找到满足m*n = N的可能中使得m>=n且m-n最小。在m*n的矩阵中按照数组从大到小以顺时针方向依次填写。

思路分析:

  1. 数组排序
  2. 将矩阵从外圈到内圈依次赋值,每一圈按照 上右下左的顺序填充,并且最后一个不填。每一圈给定两个坐标,左上角和右下角。(i,j), (a[0],a[1]);每填充一圈
    i++,j++, a[0]–,a[1]–.即向内缩一圈。当i <= a[0] && j <= a[1]填充结束。最后一圈如果左上角和右下角行值相等,i = a[0]则为横线只有列值增加填充,如果左上角和右下角列值相等,j = a[1]则为竖线只有行值增加填充。
    在这里插入图片描述

坑点

数组不能开在main函数中,否则会发生栈溢出,3,5测试点不过。需要设置为全局变量,或者使用vector.因为vector内存空间是动态分配的,所以在堆上,空间大些。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
bool cmp(int a, int b) {
	return a > b;
}
void getRC(int n, int a[]);
const int maxn = 10010;
int c[maxn];
int mp[maxn][maxn];
int main(int argc, char** argv) {
	int n, i = 0, j = 0;
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", &c[i]);
	sort(c, c + n, cmp);
	int a[2], k = 0, t;
	getRC(n, a);
	int r = a[0], co = a[1];
	i = 0; 
//	t = ((a[1] & 1) == 0 ? a[1] / 2 : a[1] / 2 + 1); // == 的优先级大于  &
	// 从外到里一圈一圈赋值,不要每一边得尾。
	for (int m = 0; i < a[0] && j < a[1]; m++) {
        if (j == a[1] - 1 ) { // 最后一次若左上角和右下角列值相等。
            for (; i < a[0]; i++)
                mp[i][j] = c[k++];
        } else if(i == a[0] - 1) { // 左上角右下角行相等 
            for (; j < a[1]; j++)
                mp[i][j] = c[k++];        	
		} else {
            for (; j < a[1] - 1; j++)
                mp[i][j] = c[k++];
            for (; i < a[0] - 1; i++)
                mp[i][j] = c[k++];
            for (; j > m; j--)
                mp[i][j] = c[k++];
            for (; i > m; i--)
                mp[i][j] = c[k++];
        }
        i++;
        j++;
		a[0]--;
		a[1]--;
	}
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < co; j++) {
			if (j == co - 1)
				printf("%d\n", mp[i][j]);
			else
				printf("%d ", mp[i][j]);
		}
	}
	return 0;
}
void getRC(int n, int a[]) {
	int sub = n;
	a[0] = -1;
	for (int i = 2; i * i <= n; i++) {
		if (n % i == 0) {
			if ((n / i - i) < sub) { // 可以不加判断直接赋值,因为遍历过程左右边界是往里扩的,差值只会越来越小。
				a[0] = n / i;
				a[1] = i;
				sub = a[0] - a[1];
			}
		}
	}
	if (a[0] == -1) {
        a[0] = n;
        a[1] = 1;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值