循环赛日程表,在这篇文章已经说的很详细了http://blog.csdn.net/liufeng_king/article/details/8488421
这里多介绍一个细节,并详细解释数组指针
#include<iostream>
#include<stdio.h>
using namespace std;
void Round_Robin_Calendar(int **a,int k,int n)
{
int i,j,s,t;
for(i=1; i<=n; i++)
a[1][i]=i;
int m=1;
for(s=1; s<=k; s++)
{
n/=2;
for(t=1; t<=n; t++)//每次填充时,起始填充位置
for(i=m+1; i<=2*m; i++)//i控制行
for(j=m+1; j<=2*m; j++)//j控制列
{
a[i][j+(t-1)*2*m]=a[i-m][j+(t-1)*2*m-m];//右下角等于左上角的值,(t-1)*2*m表示每隔2*m列循环填充一次a[i][j],循环次数由for(t=1; t<=n; t++)决定
a[i][j+(t-1)*2*m-m]=a[i-m][j+(t-1)*2*m];//左下角等于右上角的值
}
m*=2;
}
}
int main()
{
int k,n=1,i;
cout<<"enter k:"<<endl;
cin>>k;//n=2的k次方个选手参加比赛
for(i=1; i<=k; i++)
n*=2;
int **a=new int *[n+1]; //根据n动态分配二维数组a
for(i=0;i<=n;i++)
a[i]=new int[n+1];
Round_Robin_Calendar(a,k,n);
for(i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
cout<<a[i][j]<<' ';
cout<<endl;
}
for(i=0;i<=n;i++)
delete [] a[i];//释放空间
delete a;
return 0;
}
在这个程序里,用到二级指针与数组指针,之后二级指针又有二维数组形式的应用,不容易理解。
1.先看这一句:
int **a=new int *[n+1];
这个形式不常见,更简单类似的例子有:
int *a=new int[n+1];
这个大家都知道:
—–new int[n+1] 新申请一段可以保存n+1个int型整数的内存空间
—–int* a 定义一个int型指针
—–int *a=new int[n+1]就是让int型指针指向申请的内存空间的首地址!
a是一个数组指针
(数组指针:a pointer to an array,指向数组的指针
区别于指针数组:array of pointers,用于存储指针的数组,也就是数组元素都是指针)
此时可以把a直接看作数组
可以这样用:a[5]=5;
(二级指针:任何值都有地址 ,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址 ,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址)
2.而对于
int **a=new int *[n+1];
—–先定义二级指针 int **a;
—–然后分配n+1个int *型数的空间,
—–a指向这个空间的首地址,此时,分配的每个空间内存放的是int *型数据。
—–for(i=0;i<=n;i++)
a[i]=new int[n+1];
这里的a[i]可以理解为int *a=new int里面的a
所以把a当作二维数组使用,就有a[i][j],这里面存放的是int型数,即我们需要计算使用的数!
—–这里有一个优点:
此时在函数内使用时,不会因为传值调用产生问题!
可以直接在函数外使用函数内已经处理过的二级指针a(或二维数组)
比如在函数内赋值:a[1][2]=5;
在函外输出指针内的数值:cout<<a[1][2];