首页 > 试题广场 >

操作矩形

[编程题]操作矩形
  • 热度指数:618 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

平面上有一个矩形,大小为n×m,其中,长度为n的边是竖直的,长度为m的边是水平的。将矩形切割成n×m个小正方形,规定左上角的小正方形坐标为,左下角的小正方形坐标为,右上角的小正方形坐标为,右下角的小正方形坐标为。从上往下数第x行,从左往右数第列的小正方形坐标为(x,y).

现在,我们对这个矩形进行如下操作,将其顺时针旋转90度x次,然后将其水平翻转y次,然后将其逆时针旋转90度z次。

接着,我们将这个操作后的矩形重新标上坐标,每一个小正方形就有一个原来的坐标和新的坐标。

然后有Q个询问,每一次询问一个原来坐标为的小正方形的新坐标。你需要对所有询问作出回答。


输入描述:

输入第一行包含三个数x ,y ,z ,代表顺时针旋转,水平翻转,逆时针旋转的次数。

接下来一行两个数,n,m代表原矩形的大小。

接下来一行一个数,Q代表询问次数。

接下来Q行,每行两个数x,y,代表一次询问,询问原矩形中坐标为(x,y)的点现在的新坐标



输出描述:

输出包含Q行,每一行一个答案。  

示例1

输入

1 1 1
4 5
3
1 1
3 4
2 5

输出

4 1
2 4
3 5

说明

进行一次顺时针旋转,原来第i行就变成倒数第i列,第j列就变成第j行,逆时针旋转相反;水平反转仅将原来第j列变成倒数第j列。直接坐标变换就行,但是我们注意到一个细节,逆时针或顺时针旋转4次相当于没转,水平反转2次相当于没转,因此可以通过取模进一步降低时间复杂度。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static int n;
    public static int m;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] params = br.readLine().trim().split(" ");
        int x = Integer.parseInt(params[0]);
        int y = Integer.parseInt(params[1]);
        int z = Integer.parseInt(params[2]);
        params = br.readLine().trim().split(" ");
        int rows = Integer.parseInt(params[0]);
        int cols = Integer.parseInt(params[1]);
        int q = Integer.parseInt(br.readLine());
        for(int i = 0; i < q; i++){
            n = rows;
            m = cols;
            params = br.readLine().trim().split(" ");
            int x1 = Integer.parseInt(params[0]);
            int x2 = Integer.parseInt(params[1]);
            int[] pos = new int[]{x1, x2};
            pos = antiClockwise(flip(clockwise(pos, x), y), z);
            System.out.println(pos[0] + " " + pos[1]);
        }
    }
    
    private static int[] clockwise(int[] pos, int times){
        times %= 4;
        while(times-- > 0){
            // 每旋转一次会行列尺寸互换
            n = n ^ m;
            m = n ^ m;
            n = n ^ m;
            // 坐标变换
            int temp = m - pos[0] + 1;
            pos[0] = pos[1];
            pos[1] = temp;
        }
        return pos;
    }
    
    private static int[] flip(int[] pos, int times){
        if(times % 2 == 1)
            pos[1] = m - pos[1] + 1;
        return pos;
    }
    
    private static int[] antiClockwise(int[] pos, int times){
        times %= 4;
        while(times-- > 0){
            n = n ^ m;
            m = n ^ m;
            n = n ^ m;
            int temp = pos[0];
            pos[0] = n - pos[1] + 1;
            pos[1] = temp;
        }
        return pos;
    }
}

发表于 2021-09-02 14:12:18 回复(0)
服了,明明都是这么写的,怎么只有我过80%,已经照着第一个佬的java完全照搬了还是不行,还有示例给的第三个测点过程错的。
#include <iostream>
#include <algorithm>

using namespace std;

int x,y,z,n,m;

void revolve_s(int &x, int &y, int times)
{
    times %= 4;
    while (times -- )
    {
        swap(m, n);
        int t = m + 1 - x;
        x = y;
        y = t;
    }
}

void revolve_n(int &x, int &y, int times)
{
    times %= 4;
    while (times -- )
    {
        swap(m, n);
        int t = x;
        x = n + 1 - y;
        y = t;
    }
}

void flip(int &x, int &y, int times)
{
    if (times % 2) y = m + 1 - y;
}

int main()
{
    cin >> x >> y >> z;
    cin >> n >> m;
    
    int t;
    cin >> t;
    while (t -- )
    {
        int a, b;
        cin >> a >> b;
        // cout << a << " " << b << " -> ";
        revolve_s(a, b, x);
        // cout << a << " " << b << " -> ";
        flip(a, b, y);
        // cout << a << " " << b << " -> ";
        revolve_n(a, b, z);
        cout << a << " " << b << endl;
    }
    return 0;
}



编辑于 2023-05-08 18:51:03 回复(1)
import java.util.*;

public class Main{

    public static void main(String[] args){
        
        Scanner sc = new Scanner(System.in);
        int x = sc.nextInt();
        int y = sc.nextInt();
        int z = sc.nextInt();
        x = x % 4;
        y = y % 2;
        z = z % 4;
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        int q = sc.nextInt();
        while(q>0){
            int a=sc.nextInt()-1;
            int b=sc.nextInt()-1;
            int newa=a,newb=b;
            int row=n;
            int col=m;
            //顺时针90°,操作x次
            for(int i=0;i<x;i++){
                newa=b;
                newb=row-1-a;
                a=newa;
                b=newb;
                if(row==n){
                    row=m;
                    col=n;
                }
                else {
                    row=n;
                    col=m;
                }
            }
            //水平翻转,如果有,操作1次
            if(y==1){
                newb=col-1-b;
                b=newb;
            }
            //逆时针90°,操作z次
            for(int i=0;i<z;i++){
                newa=col-1-b;
                newb=a;
                a=newa;
                b=newb;
                if(row==n){
                    row=m;
                    col=n;
                }
                else {
                    row=n;
                    col=m;
                }
            }
            a++;
            b++;
            System.out.println(a+" "+b);
            q--;
 
        }
    }
}
发表于 2022-09-07 04:12:05 回复(0)
# point[0n,1m,2x,3y]
# 水平翻转,nm不变,翻转一次换y坐标,x坐标不变
def levelreverse(point):
    p0 = point
    p0[3] = point[1] - point[3] + 1    
    return p0

def Rotation90(point):
    p0 = []
    p0.append( point[1])
    p0.append( point[0])
    p0.append( point[3])
    p0.append( point[0] -  point[2] + 1)
    return p0

# xyz[0顺90,1水平,2逆90]
xyz = list(map(int, input().split())) 
nm = list(map(int, input().split())) 
Q = int(input())

while Q:
    pq = list(map(int, input().split()))
    point = []
    point = point + nm + pq

    for i in range( (xyz[0]+4)%4 ):
        point = Rotation90(point)

    if (xyz[1]+2)%2 == 1: 
        point = levelreverse(point)

    for i in range((8-((xyz[2]+4)%4))%4):
        #print(i)
        point = Rotation90(point)

    outp = list(map(str, point[2:4]))
    print(' '.join(outp))
    Q -=1

发表于 2022-08-31 22:44:53 回复(0)
先捋清楚,翻转和旋转的变化情况就好
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] nums = br.readLine().split(" ");
        int o = Integer.parseInt(nums[0]);
        int p = Integer.parseInt(nums[1]);
        int q = Integer.parseInt(nums[2]);
        String[] size = br.readLine().split(" ");
        int nn = Integer.parseInt(size[0]);
        int mm = Integer.parseInt(size[1]);
        int times = Integer.parseInt(br.readLine());

        for(int i = 0; i < times; ++i){
            int n = nn;
            int m = mm;
            String[] s = br.readLine().split(" ");
            int x = Integer.parseInt(s[0]);
            int y = Integer.parseInt(s[1]);
            int tmpX = 0;
            int tmpY = 0;
            switch(o % 4){
                case 1:
                    tmpX = y;
                    tmpY = n - x + 1;
                    x = tmpX;
                    y = tmpY;
                    break;
                case 2:
                    tmpX = m - x + 1;
                    tmpY = n - y + 1;
                    x = tmpX;
                    y = tmpY;
                    break;
                case 3:
                    tmpX = m - y + 1;
                    tmpY = x;
                    x = tmpX;
                    y = tmpY;
                    break;
                default:
                    break;
            }
            if(o % 2 == 1){
                int tmp = m;
                m = n;
                n = tmp;
            }
            if(p % 2 == 1){
                y = m - y + 1;
            }

            switch (q % 4){
                case 1:
                    tmpX = m - y + 1;
                    tmpY = x;
                    x = tmpX;
                    y = tmpY;
                    break;
                case 2:
                    tmpX = m - x + 1;
                    tmpY = n - y + 1;
                    x = tmpX;
                    y = tmpY;
                    break;
                case 3:
                    tmpX = y;
                    tmpY = n - x + 1;
                    x = tmpX;
                    y = tmpY;
                    break;
                default:
                    break;
            }
            System.out.println(x + " " + y);
        }

发表于 2022-08-27 21:26:13 回复(0)
    c++版本 坐标变换
#include<bits/stdc++.h>
using namespace std;
void cycle(pair<int,int> shape,pair<int,int> &position,int time)
{
    for(int i=1;i<time+1;i++)
    {
    int row=shape.first;
    int cow=shape.second;
    if(i%2==0)
    {
        swap(row,cow);
    }
    int temp=position.second;
    position.second=row-position.first+1;
    position.first=temp;
    }
}
void revesecycle(pair<int,int> shape,pair<int,int> &position,int time)
{
    for(int i=1;i<time+1;i++)
    {
    int row=shape.first;
    int cow=shape.second;
    if(i%2==0)
    {
        swap(row,cow);
    }
    int temp=position.first;
    position.first=cow-position.second+1;
    position.second=temp;
    }
}
void mirror(pair<int,int>shape,pair<int,int> &position,int time)
{
    if(time%2==0)
    {
        return ;
    }
    else
    {
        position.second=shape.second-position.second+1;
        return ;
    }
}
int main()
{
    int exce[3];
    for(int i=0;i<3;i++)
    {
        cin>>exce[i];
    }
    pair<int,int> shape;
    cin>>shape.first;
    int row=shape.first;
    cin>>shape.second;
    int cow=shape.second;
    int nums;
    cin>>nums;
    for(int i=0;i<nums;i++)
    {
        shape.first=row;
        shape.second=cow;
        pair<int,int> temp;
        cin>>temp.first>>temp.second;
        cycle(shape,temp,exce[0]);
        if(exce[0]%2==1)
        {
            swap(shape.first,shape.second);
        }
        mirror(shape,temp,exce[1]);
        revesecycle(shape,temp,exce[2]);
        cout<<temp.first<<' '<<temp.second<<endl;
    }
    return

发表于 2021-10-28 11:30:18 回复(0)