1105 Spiral Matrix (25分) C++

1105 Spiral Matrix

题目描述

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 1 0 4 10^4 104​. 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.计算行列数, r o w ∗ c o l = N , r o w > = c o l 且 差 值 最 小 row*col = N ,row >= col 且差值最小 rowcol=Nrow>=col
就是对N求差值最小的因数分解

2.排序;
sort解决,默认是升序,填入数字时从后往前

3.控制数字填入位置;
右->下->左->上->右->下…,用常量数组控制方向,简化代码

代码

#include <iostream>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
using namespace std;
#define DEBUG
#ifdef DEBUG
#define cin ifile
ifstream ifile("input.txt");
#endif

const int MAXN = 100000+10;

const int dir[8] = {
	0,1	//right
	,1,0 //down
	,0,-1 //left
	,-1,0 //up
};

int main(){
	int N;
	cin>>N;
	int nums[MAXN] = {0};
	int res[101][101]={0};
	
	for(int i=0;i<N;++i){
		cin>>nums[i];
	}
	
	//calculate width and height
	int w=sqrt(N),h = 1;
	while(N%w != 0){
		w--;
	}
	h = N / w;
	
	//sort as ascend
	sort(nums,nums+N);	
	
	int tm=0,tn = 0, m = 0,n = 0,base = 0 ;
	for(int i=0;i<N;++i){
		res[m][n] = nums[N-i-1];
		
		//last number needn't to calculate next position
		if(i == N-1){
			break;
		}
		
		//calculate next potential postion
		tm += dir[2*base];
		tn += dir[2*base+1];
		
		//change direction when potential position is out of range or has been filled
		while(tm < 0 || tm >= h || tn < 0 || tn >= w || res[tm][tn] > 0){
			tm = m;
			tn = n;
			base = (base+1)%4;
			tm += dir[2*base];
			tn += dir[2*base+1];
		}
		m = tm;
		n = tn;
	}
	
	for(int i=0;i<h;i++){
		for(int j=0;j<w;++j){
			if(j != 0){
				cout<<' ';
			}
			cout<<res[i][j];
		}
		if(i != h-1){
			cout<<endl;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值