这道题把N个数从大到小排列,然后按照顺时针的方向,写到一个矩形中。
这道题主要是模拟顺时针填满矩形这个过程。
这道题的核心在于定义了四个访问的方向,右,下,左,上。
int y[4]={1,0,-1,0};
int x[4]={0,1,0,-1};
按照这个方向走,如果遇到边界,则返回上一个访问的点,换一个方向走。
所以要写一个边界检测的函数,判断该点是否需要访问。
bool judge(int i,int j){
if(vis[i][j]==true||i>=m||j>=n||i<0||j<0) return false;
else return true;
}
以下是全部的代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
#include<stack>
#include<string>
#include<math.h>
using namespace std;
const int maxn=1001;
int spiral[maxn][maxn];
bool vis[maxn][maxn];
int m,n;//列0---n-1,行0---m-1
bool judge(int i,int j){
if(vis[i][j]==true||i>=m||j>=n||i<0||j<0) return false;
else return true;
}
int main(){
int N;
scanf("%d",&N);
//找到m,n
fill(spiral[0],spiral[0]+maxn*maxn,-1);
int i;
for(i=(int)sqrt(1.0*N);i>=1;i--){
if(N%i==0) break;
}
n=i,m=N/i;
priority_queue<int> in;
for(int i=0;i<N;i++){
int d;
scanf("%d",&d);
in.push(d);
}
//列0---n-1,行0---m-1
int y[4]={1,0,-1,0};
int x[4]={0,1,0,-1};
int h=0,l=-1;//定义行列的指针
int index=0;
while(in.size()>0){
h+=x[index];
l+=y[index];
if(judge(h,l)){//可以访问,放入数据
vis[h][l]=true;
spiral[h][l]=in.top();
in.pop();
}
else{//碰壁,返回
h-=x[index];
l-=y[index];
index++;
index=index%4;
}
}
for(int a=0;a<m;a++)
for(int b=0;b<n;b++){
printf("%d",spiral[a][b]);
if(b<n-1) printf(" ");
else printf("\n");
}
return 0;
}