矩阵特殊打印方式
小伙伴们大家好,好几天没更新了,主要有个比赛。从今天起继续给大家更新,今天给大家带来一种新的题型:矩阵特殊打印方式。
螺旋打印矩阵
解题思路
首先给大家看一下什么是螺旋方式打印:
就像这样一直转圈圈。
我想大多数小伙们们看到这道题目,肯定会考虑打印时,什么情况往下走,什么时候往左走,什么时候往右走,什么时候往上走,以及走到哪。当然,这种方法可以作出此题目,但太麻烦了,且耗费时间长。
这里我给出大家一种好办法:
开始时标记矩阵左上角和右下角,将外圈打印完(第一行,第5列,第3行,第1列)。然后将左上角位置横纵坐标均加一,右下角横纵坐标均减一。再次打印新的外圈。直到左上角和右下角错位代表均打印完毕。
代码分析
#include<iostream>
using namespace std;
int arr[10][10];
void printinfo(int startx,int starty,int endx,int endy){
//同行
if(startx==endx){
for(int i=starty;i<=endy;i++){
cout<<arr[startx][i]<<" ";
}
return;
}
//同列
if(starty==endy){
for(int i=startx;i<=endx;i++){
cout<<arr[i][starty]<<" ";
}
return;
}
//一般情况
for(int i=starty;i<=endy;i++){
cout<<arr[startx][i]<<" ";
}
for(int i=startx+1;i<=endx;i++){
cout<<arr[i][endy]<<" ";
}
for(int i=endy-1;i>=starty;i--){
cout<<arr[endx][i]<<" ";
}
for(int i=endx-1;i>=startx+1;i--){
cout<<arr[i][starty]<<" ";
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>arr[i][j];
}
}
int startx=0,starty=0,endx=n-1,endy=m-1;
while(startx<=endx&&starty<=endy){
printinfo(startx,starty,endx,endy);
startx++;
starty++;
endx--;
endy--;
}
}
大家要注意左上角元素和右下角元素可能处于同行或者同列。打印时注意不要重复打印!!
正方形顺时针旋转90度后打印
解题思路
这道题目我想大家都知道什么意思,就是将矩阵往右翻个再打印。
翻转后,1号元素来到3号元素位置。2号元素来到6号元素位置。3号元素来到9号元素位置......
如果我们将正方形分为两组,分别是:1、3、9、7 2、6、8、4。我们每一次循环对每一组的位置进行交换,那么当我们完成对每一组的交换后,最外圈就旋转了90度!!此时我们再将左上角和右下角分别向右下和坐上移动,让新的外圈选择90度,当左上角位置和右上角位置重合时,即代表结束。
我们考虑一般情况:正方形规模为n*n,那么我们需要分为n-1组(每一圈)。对于第i组(i从0开始编号),其左上角位置为(startx,starty),右下角位置为(endx,endy)。第一个元素其位置为arr【startx】【starty+i】,第二个元素位置为arr【startx+i】【endy】,第三个元素位置为arr【endx】【endy-i】,第四个元素位置为arr【endx-i】【starty】。对于每一组均交换四个位置元素值,完成每一圈。然后左上角和右下角位置分别往右下角和左上角移动,重复操作。知道startx>=endx(因为是正方形,横纵坐标相同)。
代码分析
#include<iostream>
using namespace std;
int arr[10][10];
void printinfo(int startx,int starty,int endx,int endy){
//组别
int size=endy-starty;
for(int i=0;i<size;i++){
//第i组第一个 arr[startx][starty+i];
//第i组第二个 arr[startx+i][endy];
//第i组第三个 arr[endx][endy-i];
//第i组第四个 arr[endx-i][starty]
//交换四个位置元素即可
int temp;
temp=arr[startx][starty+i];
arr[startx][starty+i]=arr[endx-i][starty];
arr[endx-i][starty]=arr[endx][endy-i];
arr[endx][endy-i]=arr[startx+i][endy];
arr[startx+i][endy]=temp;
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>arr[i][j];
}
}
cout<<endl;
int startx=0,starty=0,endx=n-1,endy=m-1;
while(startx<endx){
printinfo(startx,starty,endx,endy);
startx++;
starty++;
endx--;
endy--;
}
}
zigzag打印矩阵
解题思路
打印方式如上图所示。这道题我们依然使用两个位置,初始时均位于左上角 。但某种次序打印位于二者之间的元素。然后一个位置往右走,一个位置往左走,再按相反的次序打印位于二者联系之间的元素。当向右走的位置无法向右走时就向下走,当向下走的位置无法向下走时就向右走。当两者无论如何怎么走都会越界时代表结束(此时二者均在右下角)。打印次序的确定我们可以使用标志变量确定。
代码分析
#include<iostream>
using namespace std;
int arr[10][10];
void printinfo(int a,int b,int c,int d,int flag){
//左下往右上
int i,j;
if(flag>0){
i=a;
j=b;
while(i>=c&&j<=d){
cout<<arr[i][j]<<" ";
i--;
j++;
}
}
//右上向左下
else{
i=c;
j=d;
while(i<=a&&j>=b){
cout<<arr[i][j]<<" ";
i++;
j--;
}
}
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>arr[i][j];
}
}
cout<<endl;
int a,b,c,d;
a=b=c=d=0;
int flag=1;
while(a<n&&b<m&&c<n&&d<m){
printinfo(a,b,c,d,flag);
if(a<n-1){
a++;
}
else{
b++;
}
if(d<m-1){
d++;
}
else{
c++;
}
flag=-flag;
}
}
本期代码分析结束,主要是告诉大家遇见特殊矩阵打印方式时,大家能够从整体分析,而步局限于局部。多多点赞支持一下吧!!