C语言 顺时针从外往内打印n*n矩阵

panxuxuyan 2012-03-01 04:56:11
今天面试官特地跟我讨论下题 我失败了 唉!!!
1

1 2
4 3

1 2 3
8 9 4
7 6 5

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
.
.
.
n*n

...全文
1121 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
saYer 2014-01-26
  • 打赏
  • 举报
回复
思路: 行不变,列自增; 列不变,行自增; 行不变,列自减; 列不变,行自减。
代码如下:

#include <stdio.h>
#include <stdlib.h>
//int arr[10][2]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
//int arr[10][1]={1,2,3,4,5,6,7,8,9,10}; //one column
//int arr[1][10]={9,8,7,6,5,4,3,2,1,0};  //one row
//int arr[3][2]={1,2,3,4,5,6};           //Rectangular matrix
int arr[2][3]={1,2,3,4,5,6};
void matrix_printf(int start_r,int end_r,int start_c,int end_c)
{
	if( start_r > end_r || start_c > end_c )
		return;
	int r = start_r,c =start_c;
	while( c <= end_c )
	{
		printf("%d\t",arr[r][c]);
		c++;
	}

	if( start_r == end_r  ) //如果只有一行
		return;

	c--; //列下标不自减会越界
	r++; //去除拐点
	while( r <= end_r )
	{
		
		printf("%d\t",arr[r][c]);
		r++;
	}

	if( start_c == end_c ) //如果只有一列
		return;

	r--;//行下标不自减会越界
    c--;//去除拐点
	while( c >= start_c )
	{
		
		printf("%d\t",arr[r][c]);
		c--;
	}
	c++;//行下标不自加会越界
	r--;//去除拐点
	while( r > start_r )
	{
		printf("%d\t",arr[r][c]);
		r--;
	}
    putchar(10);
	matrix_printf(++start_r,--end_r,++start_c,--end_c);
}

void main()
{
	matrix_printf(0,1,0,2);
	return;
}
panxuxuyan 2012-03-13
  • 打赏
  • 举报
回复
#include<stdio.h>

main()
{
int i,j,n,k,k1,k2,p;
while(1){
printf("Please input a num:");
scanf("%d",&n);
if(!n)
return;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i<=n/2)
{
k1=i;
}
else
k1=n+1-i;
if(j<=n/2)
{
k2=j;
}
else
k2=n+1-j;

if(k1<=k2)
k=k1;
else
k=k2;

p=4*n*(k-1)-4*(k-1)*(k-1);

if(i==k){
printf("%3d ",(j+1-k)+p);
continue;
}
if(j==k){
printf("%3d ",4*(n-2*(k-1))-(i+1-k)-2+p);
continue;
}

if(j==n+1-k){
printf("%3d ",n-2*(k-1)+(i-(k-1))-1+p);
continue;
}
if(i==n+1-k){
printf("%3d ",3*(n-2*(k-1))-(j-(k-1))-1+p);
continue;
}
printf(" ?");
continue;
}
printf("\n");
}
}
}
goldbeef 2012-03-02
  • 打赏
  • 举报
回复
#include <iostream>
#define MaxEdge 10
using namespace std;

void f(int start_edge)
{
int Matrix[MaxEdge][MaxEdge];
int curt_edge;
curt_edge=start_edge;
int max_value=start_edge*start_edge;
int cur_row=1,cur_col=1;
int cur_value=1;
while (curt_edge>0)
{
int ctr_right=curt_edge;
int ctr_down=curt_edge-1;
int ctr_left=curt_edge-1;
int ctr_up=curt_edge-2;
//write right side
while (ctr_right>0)
{
Matrix[cur_row][cur_col]=cur_value;
cur_col++;
cur_value++;
ctr_right--;
}
//chage to down
cur_row++;
cur_col--;
//write down side
while (ctr_down>0)
{
Matrix[cur_row][cur_col]=cur_value;
cur_row++;
cur_value++;
ctr_down--;
}
//chage to left
cur_col--;
cur_row--;
//write left side
while (ctr_left>0)
{
Matrix[cur_row][cur_col]=cur_value;
cur_col--;
cur_value++;
ctr_left--;
}
//chage to up
cur_row--;
cur_col++;
//write up side
while (ctr_up>0)
{
Matrix[cur_row][cur_col]=cur_value;
cur_row--;
cur_value++;
ctr_up--;
}
//chage to right
cur_col++;
cur_row++;
if (cur_value>max_value)
{
break;
}

curt_edge-=2;
}
//show matrix
int i,j;
for (i=1;i<=start_edge;i++)
{
for (j=1;j<=start_edge;j++)
{
cout<<Matrix[i][j]<<" ";
}
cout<<endl;
}
}

int main()
{
int start_edge;
cin>>start_edge;
while (start_edge>0)
{
f(start_edge);
cin>>start_edge;
}
return 0;
}


矩阵是用栈表示的,有MaxEdge表示最大边,可修改
当然矩阵也可以动态表示
赵4老师 2012-03-02
  • 打赏
  • 举报
回复
把自己想象成一只蚂蚁……
cao_julians 2012-03-02
  • 打赏
  • 举报
回复
四个方向的步进,方向的调整(当前起点与终点的确定)
就有这么点事情。
zwb8848happy 2012-03-02
  • 打赏
  • 举报
回复
这题是蛇形填数,在《算法入门经典》上看到一个很好的思路。。。

代码如下:

#include <stdio.h>
#include <string.h>

int a[20][20];

void Translate(int n);
void Output(int n);

int main()
{
int n;
while (printf("Please Input a Num: "),scanf("%d",&n)!=EOF)
{
Translate(n);
Output(n);
printf("\n");
}

return 0;
}

void Translate(int n)
{
int i,j,count=0;

memset(a,0,sizeof(a));
a[i=0][j=0]=++count;

while(count<n*n)
{
while (j+1<n&&a[i][j+1]==0)
{
a[i][++j]=++count;
}
while (i+1<n&&a[i+1][j]==0)
{
a[++i][j]=++count;
}
while (j-1>=0&&a[i][j-1]==0)
{
a[i][--j]=++count;
}
while(i-1>=0&&a[i-1][j]==0)
{
a[--i][j]=++count;
}
}
}

void Output(int n)
{
int i,j;
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
printf("%4d",a[i][j]);
}
printf("\n");
}
}


我们的原则是:
先判断,在移动,而不是走一步以后发现越界了再退回来。
这样我们需要预判,即是否越界,以及如果继续往下走下去会不会达到一个已经填过的的格子!

希望对LZ有帮助。。。
Boover 2012-03-02
  • 打赏
  • 举报
回复
#include<stdio.h>

void fill_matrix(int a[][100], int n);
void print_matrix(int a[][100], int n);

int main()
{
int matrix[100][100];
int n;
printf("n=");
scanf("%d", &n);
if(n<=0 || n>100)
{
printf("out of range, n is a positive integer not bigger than 100\n");
return 1;
}
fill_matrix(matrix, n);
print_matrix(matrix, n);

return 0;
}

void fill_matrix(int a[][100], int n)
{
int i, j, l;
j = 1; //填充的数字
l = 0; //标示正在处理第几层,依次0,1,2……
while(1)
{
//n=1和n=2特殊情况,直接填充进去
if(n==1)
{
a[l][l] = j;
break;
}
else if(n==2)
{
a[l][l] = j + 0;
a[l][l+1] = j + 1;
a[l+1][l+1] = j + 2;
a[l+1][l] = j + 3;
break;
}
else
{
for(i=0; i<n; i++, j++)
a[l][l+i] = j;
for(i=1; i<n; i++, j++)
a[l+i][l+n-1] = j;
for(i=n-2; i>-1; i--, j++)
a[l+n-1][l+i] = j;
for(i=n-2; i>0; i--, j++)
a[l+i][l] = j;
n=n-2;
l++;
}
}
}

void print_matrix(int a[][100], int n)
{
int i, j;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
querdaizhi 2012-03-01
  • 打赏
  • 举报
回复
额,理解错了题目意思。再发一遍、

#include<iostream>
using namespace std;

int main()
{
int n;
cin >> n;
int a[100][100];
int temp=1;
for(int i=0;i<n;i++)
{
for(int j=i;j<n-i;j++)
{
a[i][j] = temp++;
}
for(int k=i+1;k<n-i;k++)
{
a[k][j-1] = temp++;
}
for(int x=j-2;x>=i;x--)
{
a[k-1][x] = temp++;
}
for(int y=k-2;y>i;y--)
{
a[y][x+1] = temp++;
}
}
for(i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return 0;
}

querdaizhi 2012-03-01
  • 打赏
  • 举报
回复

#include<iostream>
using namespace std;

int main()
{
int n;
cin >> n;
int a[100][100];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin >>a[i][j];
for(i=0;i<n;i++)
{
for(int j=i;j<n-i;j++)
{
cout<<a[i][j]<<" ";
}
for(int k=i+1;k<n-i;k++)
{
cout<<a[k][j-1]<<" ";
}
for(int x=j-2;x>=i;x--)
{
cout<<a[k-1][x]<<" ";
}
for(int y=k-2;y>i;y--)
{
cout<<a[y][x+1]<<" ";
}
}
cout<<endl;
return 0;
}

尘缘udbwcso 2012-03-01
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <malloc.h>
void helix(int start, int d, int n, int **arr, int line)
{
int i, j;
if(d <= 0)
{
if(line % 2 != 0)
arr[start][start] = ++n;
return;
}
i = start;
for(j = start; j < start + d; ++j)
arr[i][j] = ++n;
for(; i < start + d; ++i)
arr[i][j] = ++n;
for(; j > start; --j)
arr[i][j] = ++n;
for(; i > start; --i)
arr[i][j] = ++n;
d -= 2;
helix(++start, d, n, arr, line);

}
int main()
{
int n = 4, i, j;
int **array;
array = (int**)malloc(sizeof(int*)*n);
for(i = 0; i < n; ++i)
array[i] = (int*)malloc(sizeof(int)*n);
helix(0, n-1, 0, array, n);

for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
printf("%5d", array[i][j]);
printf("\n");
}

for(i = 0; i < n; ++i)
free(array[i]);
free(array);

return 0;
}

jm7564397 2012-03-01
  • 打赏
  • 举报
回复

#include <stdio.h>

void go(int n);
void fun(int frist,int num,int row);

int a[100][100];
int sum;
int main(){
int n;
scanf("%d",&n);
getchar();
sum=n*n;
go(n);
getchar();
return 0;
}

void fun(int frist,int num,int row){
int i=frist;
for(;i<row;i++)a[frist][i] = ++num;
if(num==sum)return;
for(i=frist+1;i<row;i++)a[i][row-1] = ++num;
for(i=row-2;i>=frist;i--)a[row-1][i] = ++num;
for(i=row-2;i>=frist+1;i--)a[i][frist] = ++num;
if(num != sum)fun(frist+1,num,row-1);
}

void go(int n){
fun(0, 0, n);
int i=0, j=0;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
printf(" %3d ",a[i][j]);
}
puts("");
}
}

比较浪费空间 - -。
alhope 2012-03-01
  • 打赏
  • 举报
回复

int array[N][N];
static s,n;
int i,j;
for(s = 0,n= N-1;s <= n;s++,n--) {
for(i = 0,j = 0;i <= n;i++)
printf("%d",array[j][i]);
for(;j<=n;j++)
printf("%d",array[j][i]);
for(;i>=s;i--)
printf("%d",array[j][i]);
for(;j>=s;j--)
printf("%d",array[j][i]);
}

思路对不对,求指正
Kevin_qing 2012-03-01
  • 打赏
  • 举报
回复
感觉应该有更简单的算法
Kevin_qing 2012-03-01
  • 打赏
  • 举报
回复
效率不一定有上面高,只是另一种算法思路

算法如下,
1.确定x,y,处于第几圈,通过计算中点坐标间距得出\
2.确定x,y, 处于哪条边,上右下左编号0-3,判断坐标和圈数得出。
3.计算外面整圈的格子数
4.计算前面的整边格子数
5,计算x,y和边起点间距

3,4,5加起来就是应该打印的值


int getEdgeIndex(int x,int y,int n,int r){
if((y==r+1)&&(x!=n-r))
return 0;//上
if(x==n-r)
return 1;//右
if(y==n-r)
return 2;//下
if(x==r+1)
return 3;//左
assert(false);
return -1;

}
int getRingIndex(int x,int y,int n){
return (n-max(abs(n+1-2*x),abs(n+1-2*y)))/2;
}
void printMat(int n){
for(int y=1;y<=n;++y){
for(int x=1;x<=n;++x){
int r=getRingIndex(x,y,n);
int e=getEdgeIndex(x,y,n,r);
int v=0;
for(int i=0;i<r;++i)
v+=4*(n-2*i-1);

v+=e*(n-2*r-1);
switch(e){
case 0:
v+=x-r;break;
case 1:
v+=y-r;break;
case 2:
v+=n-r-x+1;break;
case 3:
v+=n-r-y+1;break;
default:
assert(false);
}
printf("%3d ",v);
}
printf("\n");
}
}
sniperhuangwei 2012-03-01
  • 打赏
  • 举报
回复
template<int R,int C>
void show()
{
int direction[4][2]={{0,1},{1,0},{0,-1},{-1,0}};

int matrix[R][C];
memset((void *)matrix,0,sizeof(int)*C*R);
int index = 0;
int i = 1;
int r = 0;
int c = -1;
while(i <= C*R)
{
int tempr = r + direction[index][0];
int tempc = c + direction[index][1];
if(tempr > R-1 || tempr < 0 || tempc > C-1 || tempc < 0 || matrix[tempr][tempc] > 0)
index = (index + 1) % 4;
r += direction[index][0], c += direction[index][1];
matrix[r][c] = i++;
}
for(int i = 0; i < R; ++i)
{
for(int j = 0; j < C; ++j)
if(matrix[i][j] > 9)
printf(" %d",matrix[i][j]);
else
printf(" %d",matrix[i][j]);
printf("/n");
}
}
alhope 2012-03-01
  • 打赏
  • 举报
回复
刚发现这是一个递归问题,先顺时针打印n*n矩阵最外面一层,再打印(n-1)*(n-1)矩阵,直到没有数据
alhope 2012-03-01
  • 打赏
  • 举报
回复
设置一个指针用来跟踪打印路径point_route,一个变量用来当临界条件edg,当point_route与edg“相撞”的时候开始转变方向,同时edg也跟着改变,很笨的办法= =

坐等高手回答

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧