解题思路:
1.由题意得,需要定义一个二维数组,用来存放矩阵的数据,根据n和m的范围,定义一个二维数组 int a[505][505];
2.利用循环嵌套往数组中输入数据,从下标1开始,便于操作
3.定义一个mofa函数,用来逆时针和顺时针旋转,函数中包含四个参数,分别为中心点的横纵坐标x,y,矩阵的大小r,和翻转的方向x
4.创建一个for循环,执行m次,每次执行mofa函数,最后输出翻转后的矩阵
5.接下来处理mofa函数,定义4个形参,首先确定x和y是中心点的坐标,所以要操作的矩阵最上方最左列的的坐标可以根据r来确定,即第一个需要变动的数据位置是(x-r,y-r),后面所有需要改动的数据都是以这个点开始。
6.接着分析逆时针和顺时针如何操作,每次翻转的时候,数据都会出现变动,很有可能当某个位置的数字换成其他位置的数字时候,无法保存数据,所以我们利用两个一模一样的二维数组来操作,数组a用来当做参照数组,数组b用来翻转矩阵,每次翻转完,将数组b再次赋值给a数组
7.逆时针操作的话我们可以利用技巧,将逆时针旋转后的数据和原来的数据的位置坐标按照一行一行的来对比,找出规律,分析行列是如何变化的,然后根据for循环嵌套的规律,依次将a数组中的值放入b数组中。
8.每次旋转都会涉及到一个b数组坐标的位置,需要先累加列坐标,执行完依次内循环后,再累加横坐标
- #include
- using namespace std;
- int a[505][505],b[505][505];
- int n,m;
- void mofa(int x,int y,int r,int z)
- {
- int xx=x-r-1,yy=y-r-1;//xx和yy为被赋值的数组下标
- if(z==0)//如果是顺时针旋转的话
- {
- for(int j=y-r;j<=y+r;j++)//列数从小到大
- {
- xx++; //行数加1
- for(int i=x+r;i>=x-r;i--)//行数从大到小
- {
- yy++;//列数增加1
- b[xx][yy]=a[i][j];
- }
- yy=y-r-1;//一行结束,开始下一行,列数初始化
- }
- }
- else//如果是逆时针的话
- {
- for(int j=y+r;j>=y-r;j--)//列数从大到小
- {
- xx++;
- for(int i=x-r;i<=x+r;i++)//行数从小到大
- {
- yy++;
- b[xx][yy]=a[i][j];
- }
- yy=y-r-1;
- }
- }
- for(int i=x-r;i<=x+r;i++)//更新数组a
- {
- for(int j=y-r;j<=y+r;j++)
- {
- a[i][j]=b[i][j];
- }
- }
- }
- int main()
- {
- cin>>n>>m;
- int num=0;
- for(int i=1;i<=n;i++)
- for(int j=1;j<=n;j++)
- {
- num++;//数组元素
- a[i][j]=num;//将数字填入到a数组中
- b[i][j]=a[i][j];//将数组a赋值给数组b
- }
- int x,y,r,z;
- for(int i=1;i<=m;i++)
- {
- cin>>x>>y>>r>>z;
- mofa(x,y,r,z);//开始旋转
- }
- for(int i=1;i<=n;i++)//输出数组
- {
- for(int j=1;j<=n;j++)
- cout<" ";
- cout<
- }
- return 0;
- }