PAT 1105 C++

1.题意

给出一串数字,让你给出该串数字从大到小的螺旋输出。

2.分析

我依稀记得,我在大二的时候,就写过这道题,但是当时我一下午的时间都没有写出这道题。原因很简单,我拿到题目只有就是写写写,而不懂得思考,导致写了一下午也没有任何的结果。后来我慢慢知道了,只有将题目高度抽象,才可以快速的解出题目。 分析过程如下:
PAT 1105 C++ 版_# PAT
注意这里的蓝色框框中的东西代表的就是 最后抽象出来的东西,这个可以帮助我们解题,我们写代码只需要实现这个过程即可。

3.代码

#include<cstdio>
#include<functional>
#include<algorithm>
#include<iostream>
#define maxn 100005 
using namespace std;

//获取两个值m和n
//满足的关系式:m>=n ,且 (m-n) 的值取到最小 
int getLeft(int number){
	int i,j;
	//cout <<"sqrt(number) = "<<sqrt(number)<<"\n";
	if(number == 1 ) return 1;
	for(i = sqrt(number) ; i <= number ;i++ ){		
		if(number % i == 0) {			
			return max(i,number/i);	
		}
	}
} 

//用于存储结果的数组 
int input[maxn];
 
int main(){
	int N;
	cin >> N;
	int i,j;
	int m,n;
	m = getLeft(N);
	n = N / m;
	int res[m][n]; 
	
	for(i = 0;i< N;i++){
		cin >> input[i];
	}
	
	for(i = 0;i<m;i++){
		for(j = 0;j<n;j++){
			res[i][j] = 0;//为结果集赋值 
		} 
	}
	sort(input,input+N,greater<int>());	
	
	int index = 0;//表示的是元素总数目 
	i = 0;j = -1;//reset to 0	
	while( index < N ){
		//向右方向 
		while(res[i][j+1]==0 && i<m && (j+1)<n){			
			j++;
			res[i][j] = input[index];
			index ++;
		}
		//向下方向
		while(res[i+1][j]==0 && (i+1)<m && j<n){ //这里的判断条件应该是 (i+1) < m
			i++;
			res[i][j] = input[index];			
			index ++;
		}
		
		//向左方向
		while(res[i][j-1]==0 && i<m && j<n && (j-1)>=0 && i>=0){
			j--;
			res[i][j] = input[index];			
			index ++;
		}
		
		//向上方向
		while(res[i-1][j]==0 && i<m && j<n && j>=0 && (i-1)>0){//在i变化的时候,如果j=0也是正确的 
			i--;
			res[i][j] = input[index];			
			index ++;
		}
	} 
	
	for(i = 0;i< m;i++){
		for(j = 0;j< n;j++){
			cout << res[i][j];
			if(j!=n-1) cout <<" ";
		}cout<<"\n";
	}
}

4.测试用例

12
37 76 20 98 76 42 53 95 60 81 58 93

9 
1 2 3 4 5 6 7 8 9

8
1 2 3 4 5 6 7 8

1
1

2 
1 2

5.执行结果

两遍AC

6.注意事项

  • #define maxn 100005maxn的值的范围
  • 我很惊讶,为啥使用sqrt()函数非要cmath这个头文件,明明使用algorithm也是可以的。