洛谷-P4924

一、题目描述


二、题解

       1. 解题思路与方法   

        矩阵操作题,根据输入的要求对方阵内的某个方阵进行顺逆时针的90°旋转。核心难点在于如何对给定方阵内的小方阵进行旋转并将原方阵的值更新为旋转后的值,因此需要考虑两个问题:1.如何处理旋转操作?显而易见的是,在原方阵中进行旋转操作并不容易,但要旋转的方阵的大小已知,因此不妨将需要旋转的方阵提取出来,单独进行旋转操作,操作完成后将原方阵对应位置的值更新。  2.何时进行原方阵的更新?由于每次操作的方阵大小和在原方阵中的位置不固定,因此在每次执行完旋转操作后,都应该及时更新原方阵的值,在操作输入完成后,原方阵的值就已经被更新为最终答案,直接输出即可。

矩阵旋转规律—以顺时针旋转90°为例:


       根据上图可知具体的旋转是怎么样的,因此对上图进行分析可以看出,对于旋转之前和旋转之后的矩阵,旋转后矩阵的行号对应原矩阵的列号;旋转后矩阵的列号对应(n-原矩阵行号-1)。
同样的推理可以得到逆时针旋转时矩阵对应的变化,总结一下并转换为实际代码:

temp[num][num]  //旋转后矩阵

map[num][num]  //原矩阵

temp[j][num-i-1]=map[i][j]; //顺时针  

temp[num-j-1][i]=map[i][j]; //逆时针

       2. code      

import java.util.Scanner;
public class Main{
    public static int[][] map;
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        map =new int[n][n];
        int count=1;     //从1到n*n为矩阵赋值
        for(int i=0;i<n;i++) {
            for(int j=0;j<n;j++) {
                map[i][j]=count;
                count++;
            }
        }
        for(int i=0;i<m;i++) {
            int x=sc.nextInt()-1;
            int y=sc.nextInt()-1;
            int r=sc.nextInt();
            int z=sc.nextInt();//按题意依次读入x y r z
            revolve(x,y,r,z);//旋转并更新原矩阵

        }
        for(int i=0;i<n;i++) {//输出即可
            for(int j=0;j<n;j++) {
                System.out.print(map[i][j]+" ");
            }
            System.out.println();
        }
        sc.close();
    }

    private static void revolve(int x, int y, int r, int z) {
        int[][] temp =new int[2*r+1][2*r+1];//需要变化的数组的大小
        int[][] temp2 =new int[2*r+1][2*r+1];//旋转后数组
        for(int j=x-r;j<=x+r;j++) {
            for(int k=y-r;k<=y+r;k++) {
                temp[j-(x-r)][k-(y-r)]=map[j][k];
            }
        }
        for(int i=0;i<2*r+1;i++) {
            for(int j=0;j<2*r+1;j++) {
                if(z==0){
                    temp2[j][2*r+1-i-1]=temp[i][j];
                }else{
                    temp2[2*r+1-j-1][i]=temp[i][j];
                }
            }
        }
        for(int i=x-r;i<=x+r;i++) {
            for(int j=y-r;j<=y+r;j++) {
                map[i][j]=temp2[i-(x-r)][j-(y-r)];
            }
        }
    }
}

     

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值