1105 Spiral Matrix 给定数组向螺旋矩阵中填入数据

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1105 Spiral Matrix 给定数组向螺旋矩阵中填入数据相关的知识,希望对你有一定的参考价值。

两个测试用例超时,可直接跳转到

目录

超时点1

超时点2


​​​​​​​

要做的事情是,将数组按照非升序/降序,顺时针从外围到内部一圈一圈地把数据填到矩阵中,并打印出来。也就是将数组排好序后,将矩阵的坐标和数组的下标对应起来。

所以用一个这样的数组存放矩阵相应位置上元素的数组下标。

int mp[200][200] = {0};

起先,我这样填充每一圈(注意交点的分配)

当然,从外到内,这个圈一定是在减小的, 减小多少,我用z来控制,程序如下,4个for循环分别代表4条直线上的元素

	int idx = n-1,i,j,z=1;
	int sw = false;//stop while循环 	 
	for(z=1;;z++){
		i = z;
		if(sw)break;
		for(j=z;j<=col-z;j++){
			mp[i][j] = idx--;
//			printf("mp[%d][%d]=%d\\n",i,j,idx+1);
			if(idx<0){
				sw = 1;
				break;
			}
		}
		j = col+1-z;
		if(sw)break;
		for(i=z;i<=row-z;i++){
			mp[i][j] = idx--;
//			printf("mp[%d][%d]=%d\\n",i,j,idx+1);
			if(idx<0){
				sw = 1;
				break;
			}
		}
		i = row+1-z;
		if(sw)break;
		for(j=col-z+1;j>=z+1;j--){
			mp[i][j] = idx--;
//			printf("mp[%d][%d]=%d\\n",i,j,idx+1);
			if(idx<0){
				sw = 1;
				break;
			}
		}
		j = z;
		if(sw)break;
		for(i=row-z+1;i>=z+1;i--){
			mp[i][j] = idx--;
//			printf("mp[%d][%d]=%d\\n",i,j,idx+1);
			if(idx<0){
				sw = 1;
				break;
			}
		}
	}

至于i和j的起止到底是多少,我也不能一下子想出,但我知道肯定有对称性,于是试了出来(通过被注释掉的打印)

特别说明一下变量sw,是stop while的缩写,用于跳出while循环,且每次进入for循环之前都要判断一下sw是否为true。idx<0说明矩阵已填满。

1)每次idx--之后都判断一下idx是否<0,但是此时break,只能跳出内层for循环,要跳出外层循环还要借助sw变量。

2)何时判断sw呢?我们希望达到的效果是idx<0一旦成立,就不再填充,如果只是在刚进入while循环的时候判断一下,可能出现的情况是,在第三个for循环中断后,又进入第四个for循环,所以每次进入循环前都要判断一下sw。

但是这样做,有两个测试用例是运行超时的。我迫切地翻开参考书,想看看自己究竟哪里代码不优雅了

 1)那个sw的判断希望下次不要再看到了。直接把idx>=0放在while和for的括号里不香吗?理论上while可以不放,但是这样光标一直闪,程序会出问题。改进后如下

    int idx = n-1,i,j,z=1;
	 	 
	for(z=1;idx>=0;z++){
		
		i = z;
		for(j=z;j<=col-z&&idx>=0;j++){
			mp[i][j] = idx--;
		}
		
		j = col+1-z;
		for(i=z;i<=row-z&&idx>=0;i++){
			mp[i][j] = idx--;
		}
		
		i = row+1-z;
		for(j=col-z+1;j>=z+1&&idx>=0;j--){
			mp[i][j] = idx--;
		}
		
		j = z;
		for(i=row-z+1;i>=z+1&&idx>=0;i--){
			mp[i][j] = idx--;
		}
	}

代码清爽了很多,但是超时的问题仍毫无进展。

超时点1

2)我听参考书的话,加入了如下特判

if(n==1){
		printf("%d",a[0]);
		return 0;
	}

于是从21变成了22分,有一个测试用例通过了。还剩一个超时,并且我注意到,刚才的两个超时,显示的时间都是-,也许是陷入了某种死循环。

3)我尝试提取i和j的边界中的公因子,引入

int r = col-z;
int d = row-z;

矩阵填充代码变成如下

    int idx = n-1,i,j,z=1;
	 	 
	for(z=1;idx>=0;z++){
		
		i = z;
		int r = col-z;
		int d = row-z;
		
		for(j=z;j<=r&&idx>=0;j++){
			mp[i][j] = idx--;
		}
		
		j = r+1;
		for(i=z;i<=d&&idx>=0;i++){
			mp[i][j] = idx--;
		}
		
		i = d+1;
		for(j=r+1;j>=z+1&&idx>=0;j--){
			mp[i][j] = idx--;
		}
		
		j = z;
		for(i=d+1;i>=z+1&&idx>=0;i--){
			mp[i][j] = idx--;
		}
	}

很遗憾,那个测试用例还是没过

4)最后,我又找出自己的代码和参考书代码的一个区别,那就是我在填充过程中填充的是数组下标,而参考书直接填充的内容,这样输出的时候就不必先映射到下标再输出,于是我照做。

将所有的

mp[i][j] = idx--;

改成了

mp[i][j] = a[idx--];

于是输出时候的

int idx = mp[i][j];
printf("%d",a[idx]);

也就自然变成了

printf("%d",mp[i][j]);

还是超时。。

超时点2

5)最后,我又发现,程序对最内层只有一个数字的情况进行了特判,也就是在4个for循环后加入了如下代码

i++;
j++;
if(idx==0)mp[i][j] = a[idx--];

好了,AC。

完整代码如下

#include<cmath>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
#include<map>
#include<string>
#include<stdlib.h>

using namespace std;

const int maxn = 10010;

int mp[200][200] = {0};


int main(){
	
	int n;
	int a[maxn];
	
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
	}
	
	if(n==1){
		printf("%d",a[0]);
		return 0;
	}
	
	int col,row;
	for(int i=(int)sqrt(n);i>=1;i--){
		if(n%i==0){
			col = i;
			break;
		}
	}
	
	row = n/col;//row>=col
	
	//a按照升序排好 
	sort(a,a+n);
	
	int idx = n-1,i,j,z;
	 	 
	for(z=1;idx>=0;z++){
		
		
		
		int r = col-z;
		int d = row-z;
		
		for(i=z,j=z;j<=r&&idx>=0;j++){
			mp[i][j] = a[idx--];
		}
		
		for(i=z,j=r+1;i<=d&&idx>=0;i++){
			mp[i][j] = a[idx--];
		}
		
		for(i=d+1,j=r+1;j>=z+1&&idx>=0;j--){
			mp[i][j] = a[idx--];
		}
		
		for(i=d+1,j=z;i>=z+1&&idx>=0;i--){
			mp[i][j] = a[idx--];
		}
		
		i++;
		j++;
		if(idx==0)mp[i][j] = a[idx--];
	}
	
	
	
	for(int i=1;i<=row;i++){
		for(int j=1;j<=col;j++){
			printf("%d",mp[i][j]);
			if(j!=col)printf(" ");
		}
		printf("\\n"); 
	} 
	
	return 0;
}

以上是关于1105 Spiral Matrix 给定数组向螺旋矩阵中填入数据的主要内容,如果未能解决你的问题,请参考以下文章

A1105 Spiral Matrix (25分)

PAT A1105 Spiral Matrix [硬核模拟]

1105. Spiral Matrix (25)

1105 Spiral Matrix (25分)

PAT 1105 Spiral Matrix

1105 Spiral Matrix