一道笔试题:顺时针旋转N*N阶矩阵储存的图片:
比如 1 2 3
4 5 6
7 8 9
旋转后变为:
7 4 1
8 5 2
9 6 3
可以把该问题分解为一层一层的来做。比如上列子中,最外层的1,3,9,7轮流交换。2,6,8,4轮流交换。后者对应的坐标为[0][1] [1][2] [2[1] [1][0]。对一般的a[i][j]来说,对应的另外三个元素就是:a[j][n-1-i],a[n-i-1][n-j-1],a[j][i]。
接下来就是要确定i和j的取值范围:对应i来说,代表的是行数,行数i<n/2,比如像上面的三行的话,只需要旋转外面的一层, 也就是i等于0就行了。
对于j代表的是列数,i<=j<n-1-i;。自己画个图理解下,比如说上面的第二层,i=1,j=1,范围是【1,n-2)。
只要做题是把这两个问题理清楚了。不难写出如下代码:
for (i=0;i <n/2;i++)
{
int m=n-i*2;
if (m==1) break;
for (j=i;j <m+i-1;j++)
{
int tmp=a[i][j];
a[i][j]=a[n-j-1][i];
a[n-j-1][i]=a[n-i-1][n-j-1];
a[n-i-1][n-j-1]=a[j][n-i-1];
a[j][n-i-1]=tmp;
}
}
与此题类似的是,顺时针输入一个矩阵的元素:这道题的难度在于代码中会包含很多个循环,而且还有多个边界条件需要判断。
{
int i=0;
int max=n/2;
while(i<=max)
{
int j=i;
int k=0;
for (k=j;k<=n-i-1;k++)
{
cout<<a[i][k];
}
for (k=i+1;k<=n-i-1;k++)
{
cout<<a[k][n-1-i];
}
for (k=n-2-i;k>=i;k--)
{
cout<<a[n-1-i][k];
}
for (k=n-2-i;k>=i+1;k--)
{
cout<<a[k][i];
}
i++;
}
}