10 9 8 7
11 16 15 6
12 13 14 5
1 2 3 4
N由用户输入,请输出螺旋方阵.
这个怎么解呢?请高手给予解答,期待~
7 个解决方案
#1
#include<iostream.h>
#include<process.h>
#include<iomanip.h>
int main()
{int N,*b,d,**a;
cout<<"please input a number of array:";
cin>>N;
if((b=new int[N*N])==NULL)
{cout<<"can't allocate more memory.";
exit(1);}
a=new int *[N];
for(int c=0;c<N;c++)
a[c]=new int[N];
for(int a1=0;a1<N;a1++)
for(int a2=0;a2<N;a2++)
a[a1][a2]=0;
for(int i=0;i<N*N;i++)
b[i]=i+1;
if(N%2)
a[(N-1)/2][(N-1)/2]=N*N;
i=0;
for(d=0;d<N/2;d++)
{
for(int j=0+d;j<N-1-d;j++)
a[0+d][j]=b[i++];
for(int k=0+d;k<N-d-1;k++)
a[k][N-1-d]=b[i++];
for(int l=N-d-1;l>0+d;l--)
a[N-1-d][l]=b[i++];
for(int m=N-1-d;m>=1+d;m--)
a[m][0+d]=b[i++];
}
cout<<endl;
for(a1=0;a1<N;a1++)
{ for(a2=0;a2<N;a2++)
cout<<setw(4)<<a[a1][a2];
cout<<endl;
}
return 0;
}
#include<process.h>
#include<iomanip.h>
int main()
{int N,*b,d,**a;
cout<<"please input a number of array:";
cin>>N;
if((b=new int[N*N])==NULL)
{cout<<"can't allocate more memory.";
exit(1);}
a=new int *[N];
for(int c=0;c<N;c++)
a[c]=new int[N];
for(int a1=0;a1<N;a1++)
for(int a2=0;a2<N;a2++)
a[a1][a2]=0;
for(int i=0;i<N*N;i++)
b[i]=i+1;
if(N%2)
a[(N-1)/2][(N-1)/2]=N*N;
i=0;
for(d=0;d<N/2;d++)
{
for(int j=0+d;j<N-1-d;j++)
a[0+d][j]=b[i++];
for(int k=0+d;k<N-d-1;k++)
a[k][N-1-d]=b[i++];
for(int l=N-d-1;l>0+d;l--)
a[N-1-d][l]=b[i++];
for(int m=N-1-d;m>=1+d;m--)
a[m][0+d]=b[i++];
}
cout<<endl;
for(a1=0;a1<N;a1++)
{ for(a2=0;a2<N;a2++)
cout<<setw(4)<<a[a1][a2];
cout<<endl;
}
return 0;
}
#2
不好意思,借用一下,两个问题差不多。
1,2,3三个数的排列问题,到底有没有什么好的算法?即生成如下格式:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
1,2,3三个数的排列问题,到底有没有什么好的算法?即生成如下格式:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#3
好多教科书上有
#4
怎么没人顶呢?
#5
高手来讨论一下算法的具体思想好吗?谢谢~
#6
从1开始逆时针扫描到N(N=25),如下:
21 - 20 - 19 - 18 - 17
| |
22 7 - 6 - 5 16
| | | |
23 8 1 4 15
| | | | |
24 9 2 - 3 14
| | |
25 10 - 11- 12 - 13
看看对角线上的21,7,1,3,13,排列出来:1,3,7,13,21
规律:a[i]=i*(i-1)+1,当符合公式N=a[i],且i是整数时,此时必须转折;
例子:如果现在N=1,由公式N=a[i]计算i=1,表示1为转折点;
我们称此时对角线上的点为主转折点
-------
在看对角线25,9,1,5,17,排列后1,5,9,17,26
规律:b[i]=i*i+1,当符合公式N=b[i],且i是整数时,此时必须转折;
例子:如果现在N=5,由公式N=b[i]计算i=2,表示1为转折点;
我们称此时对角线上的点为副转折点
------
区分主、副转折点的意义:
在主转折点后的长度,比之前的长一个单位,此次转折是增加长度
例子:主转折点 13 前面(包括自己)有10,11,12,13四个数字,后面有13,14,15,16,17五个数字
在副转折点后的长度,比之前的相同,此次只为转折
例子:副转折点 10 前面(包括自己)有7,8,9,10四个数字,后面有10,11,12,13,四个数字
-------
符合公式N=a[i],N=b[i],且i为整数的,才是转折点;i标明了是第i个转折点(分主副)
21 - 20 - 19 - 18 - 17
| |
22 7 - 6 - 5 16
| | | |
23 8 1 4 15
| | | | |
24 9 2 - 3 14
| | |
25 10 - 11- 12 - 13
看看对角线上的21,7,1,3,13,排列出来:1,3,7,13,21
规律:a[i]=i*(i-1)+1,当符合公式N=a[i],且i是整数时,此时必须转折;
例子:如果现在N=1,由公式N=a[i]计算i=1,表示1为转折点;
我们称此时对角线上的点为主转折点
-------
在看对角线25,9,1,5,17,排列后1,5,9,17,26
规律:b[i]=i*i+1,当符合公式N=b[i],且i是整数时,此时必须转折;
例子:如果现在N=5,由公式N=b[i]计算i=2,表示1为转折点;
我们称此时对角线上的点为副转折点
------
区分主、副转折点的意义:
在主转折点后的长度,比之前的长一个单位,此次转折是增加长度
例子:主转折点 13 前面(包括自己)有10,11,12,13四个数字,后面有13,14,15,16,17五个数字
在副转折点后的长度,比之前的相同,此次只为转折
例子:副转折点 10 前面(包括自己)有7,8,9,10四个数字,后面有10,11,12,13,四个数字
-------
符合公式N=a[i],N=b[i],且i为整数的,才是转折点;i标明了是第i个转折点(分主副)
#7
参考http://search.csdn.net/expert/topic/6/603/2003/4/19/1680969.htm
这一大类问题通常的解法是:
1. 可以推出一个计算公式
2. 控制下标模拟
这一大类问题通常的解法是:
1. 可以推出一个计算公式
2. 控制下标模拟
#1
#include<iostream.h>
#include<process.h>
#include<iomanip.h>
int main()
{int N,*b,d,**a;
cout<<"please input a number of array:";
cin>>N;
if((b=new int[N*N])==NULL)
{cout<<"can't allocate more memory.";
exit(1);}
a=new int *[N];
for(int c=0;c<N;c++)
a[c]=new int[N];
for(int a1=0;a1<N;a1++)
for(int a2=0;a2<N;a2++)
a[a1][a2]=0;
for(int i=0;i<N*N;i++)
b[i]=i+1;
if(N%2)
a[(N-1)/2][(N-1)/2]=N*N;
i=0;
for(d=0;d<N/2;d++)
{
for(int j=0+d;j<N-1-d;j++)
a[0+d][j]=b[i++];
for(int k=0+d;k<N-d-1;k++)
a[k][N-1-d]=b[i++];
for(int l=N-d-1;l>0+d;l--)
a[N-1-d][l]=b[i++];
for(int m=N-1-d;m>=1+d;m--)
a[m][0+d]=b[i++];
}
cout<<endl;
for(a1=0;a1<N;a1++)
{ for(a2=0;a2<N;a2++)
cout<<setw(4)<<a[a1][a2];
cout<<endl;
}
return 0;
}
#include<process.h>
#include<iomanip.h>
int main()
{int N,*b,d,**a;
cout<<"please input a number of array:";
cin>>N;
if((b=new int[N*N])==NULL)
{cout<<"can't allocate more memory.";
exit(1);}
a=new int *[N];
for(int c=0;c<N;c++)
a[c]=new int[N];
for(int a1=0;a1<N;a1++)
for(int a2=0;a2<N;a2++)
a[a1][a2]=0;
for(int i=0;i<N*N;i++)
b[i]=i+1;
if(N%2)
a[(N-1)/2][(N-1)/2]=N*N;
i=0;
for(d=0;d<N/2;d++)
{
for(int j=0+d;j<N-1-d;j++)
a[0+d][j]=b[i++];
for(int k=0+d;k<N-d-1;k++)
a[k][N-1-d]=b[i++];
for(int l=N-d-1;l>0+d;l--)
a[N-1-d][l]=b[i++];
for(int m=N-1-d;m>=1+d;m--)
a[m][0+d]=b[i++];
}
cout<<endl;
for(a1=0;a1<N;a1++)
{ for(a2=0;a2<N;a2++)
cout<<setw(4)<<a[a1][a2];
cout<<endl;
}
return 0;
}
#2
不好意思,借用一下,两个问题差不多。
1,2,3三个数的排列问题,到底有没有什么好的算法?即生成如下格式:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
1,2,3三个数的排列问题,到底有没有什么好的算法?即生成如下格式:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
#3
好多教科书上有
#4
怎么没人顶呢?
#5
高手来讨论一下算法的具体思想好吗?谢谢~
#6
从1开始逆时针扫描到N(N=25),如下:
21 - 20 - 19 - 18 - 17
| |
22 7 - 6 - 5 16
| | | |
23 8 1 4 15
| | | | |
24 9 2 - 3 14
| | |
25 10 - 11- 12 - 13
看看对角线上的21,7,1,3,13,排列出来:1,3,7,13,21
规律:a[i]=i*(i-1)+1,当符合公式N=a[i],且i是整数时,此时必须转折;
例子:如果现在N=1,由公式N=a[i]计算i=1,表示1为转折点;
我们称此时对角线上的点为主转折点
-------
在看对角线25,9,1,5,17,排列后1,5,9,17,26
规律:b[i]=i*i+1,当符合公式N=b[i],且i是整数时,此时必须转折;
例子:如果现在N=5,由公式N=b[i]计算i=2,表示1为转折点;
我们称此时对角线上的点为副转折点
------
区分主、副转折点的意义:
在主转折点后的长度,比之前的长一个单位,此次转折是增加长度
例子:主转折点 13 前面(包括自己)有10,11,12,13四个数字,后面有13,14,15,16,17五个数字
在副转折点后的长度,比之前的相同,此次只为转折
例子:副转折点 10 前面(包括自己)有7,8,9,10四个数字,后面有10,11,12,13,四个数字
-------
符合公式N=a[i],N=b[i],且i为整数的,才是转折点;i标明了是第i个转折点(分主副)
21 - 20 - 19 - 18 - 17
| |
22 7 - 6 - 5 16
| | | |
23 8 1 4 15
| | | | |
24 9 2 - 3 14
| | |
25 10 - 11- 12 - 13
看看对角线上的21,7,1,3,13,排列出来:1,3,7,13,21
规律:a[i]=i*(i-1)+1,当符合公式N=a[i],且i是整数时,此时必须转折;
例子:如果现在N=1,由公式N=a[i]计算i=1,表示1为转折点;
我们称此时对角线上的点为主转折点
-------
在看对角线25,9,1,5,17,排列后1,5,9,17,26
规律:b[i]=i*i+1,当符合公式N=b[i],且i是整数时,此时必须转折;
例子:如果现在N=5,由公式N=b[i]计算i=2,表示1为转折点;
我们称此时对角线上的点为副转折点
------
区分主、副转折点的意义:
在主转折点后的长度,比之前的长一个单位,此次转折是增加长度
例子:主转折点 13 前面(包括自己)有10,11,12,13四个数字,后面有13,14,15,16,17五个数字
在副转折点后的长度,比之前的相同,此次只为转折
例子:副转折点 10 前面(包括自己)有7,8,9,10四个数字,后面有10,11,12,13,四个数字
-------
符合公式N=a[i],N=b[i],且i为整数的,才是转折点;i标明了是第i个转折点(分主副)
#7
参考http://search.csdn.net/expert/topic/6/603/2003/4/19/1680969.htm
这一大类问题通常的解法是:
1. 可以推出一个计算公式
2. 控制下标模拟
这一大类问题通常的解法是:
1. 可以推出一个计算公式
2. 控制下标模拟