ccf坐标变换(其二)(Java)

 题目

问题描述

样例输入

10 5
2 0.59
2 4.956
1 0.997
1 1.364
1 1.242
1 0.82
2 2.824
1 0.716
2 0.178
2 4.094
1 6 -953188 -946637
1 9 969538 848081
4 7 -114758 522223
1 9 -535079 601597
8 8 159430 -511187

样例输出

-1858706.758 -83259.993
-1261428.46 201113.678
-75099.123 -738950.159
-119179.897 -789457.532
114151.88 -366009.892

样例说明

第五个查询仅对输入坐标使用了操作八:拉伸 0.716 倍。

横坐标:159430×0.716=114151.88

纵坐标:−511187×0.716=−366009.892

由于具体计算方式不同,程序输出结果可能与真实值有微小差异,样例输出仅保留了三位小数。

评测用例规模与约定

80% 的测试数据满足:m,n≤1000;

全部的测试数据满足:

  • m,n≤100000;

  • 输入的坐标均为整数且绝对值不超过 1000000;

  • 单个拉伸操作的系数 k∈[0.5,2];

  • 任意操作区间 ti,⋯,tj(1≤i≤j≤n)内拉伸系数 k 的乘积在 [0.001,1000] 范围内。

评分方式

如果你输出的浮点数与参考结果相比,满足绝对误差不大于 0.1,则该测试点满分,否则不得分。

提示

  • C/C++:建议使用 double 类型存储浮点数,并使用 scanf("%lf", &x); 进行输入,printf("%f", x); 输出,也可以使用 cin 和 cout 输入输出浮点数;#include <math.h> 后可使用三角函数 cos() 和 sin()

  • Python:直接使用 print(x) 即可输出浮点数 xfrom math import cos, sin 后可使用相应三角函数。

  • Java:建议使用 double 类型存储浮点数,可以使用 System.out.print(x); 进行输出;可使用 Math.cos() 和 Math.sin() 调用三角函数。

解答1(直接模拟)

由于80% 的测试数据满足:m,n≤1000,直接模拟即可,得分80分

时间复杂度O(m*n)

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] type = new int[n + 1]; // 记录操作的类型
        double[] delta = new double[n + 1]; //记录变化量
        for (int i = 1; i <= n; i++) {
            type[i] = sc.nextInt();
            delta[i] = sc.nextDouble();
        }
        for (int i = 0; i < m; ++i) {
            int start = sc.nextInt();
            int end = sc.nextInt();
            double x = sc.nextDouble();
            double y = sc.nextDouble();
            for (int j = start; j <= end; ++j) {
                if (type[j] == 1) {    //拉伸操作
                    x *= delta[j];
                    y *= delta[j];
                } else {    //旋转操作
                    double sin = Math.sin(delta[j]), cos = Math.cos(delta[j]);
                    double tmp = x * cos - y * sin;
                    y = x * sin + y * cos;
                    x = tmp;
                }
            }
            System.out.println(x + " " + y);
        }
    }
}

解答2(极坐标+前缀和)

注意到一个操作是改变与原点的距离,一个操作是改变与x轴所夹成的角度,如果考虑坐标在极坐标系下的表示形式,会发现这两种操作只是分别对其中一维进行操作,且这些操作是可逆的,且不会相互影响。因此我们就预处理出前缀和数组。然后对于一个点问经过操作start到end的结果,先对它施加start到end操作的影响,再消除1到start - 1操作的影响,即可得到start到end操作的结果。

施加影响,就是长度*k,角度 +θ,消除影响,就是长度 / k,角度 −θ。

最后根据r和 θ 还原出x=rcosθ,y=rsinθ。

时间复杂度为 O(n+m).

import java.util.Scanner;
/*
 * 极坐标+前缀和 O(m + n) 100分
 * */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        double[] side = new double[n + 1]; //坐标伸缩量的前缀和
        double[] rad = new double[n + 1];    //弧度变化量的前缀和
        side[0] = 1.0;
        //预处理前缀和数组
        for (int i = 1; i < n + 1; i++) {
            int type = sc.nextInt();
            double delta = sc.nextDouble();
            if (type == 1) {
                side[i] = delta * side[i - 1];
                rad[i] = rad[i - 1];
            } else {
                rad[i] = delta + rad[i - 1];
                side[i] = side[i - 1];
            }
        }
        for (int i = 0; i < m; i++) {
            int start = sc.nextInt();
            int end = sc.nextInt();
            double x = sc.nextDouble();
            double y = sc.nextDouble();
            //起始点的极坐标r,Θ
            double r = Math.sqrt(x * x + y * y);
            double theta = Math.atan2(y, x);
            //执行start到end的一系列操作
            r *= side[end] / side[start - 1];
            theta += rad[end] - rad[start - 1];
            //最后得出该点的平面直角坐标
            x = r * Math.cos(theta);
            y = r * Math.sin(theta);
            System.out.println(x + " " + y);
        }
    }
}

### 回答1: Java中的屏幕坐标单位是像素(pixel)。像素是计算机显示屏上的最小单位,每个像素都可以显示不同的颜色和亮度。在Java中,使用像素来描述图形界面中的组件位置和大小。例如,一个按钮可以在屏幕上被定义为宽度为100像素,高度为50像素的矩形区域。 ### 回答2: 在Java中,屏幕坐标单位使用像素(Pixel)作为度量单位。像素是屏幕上最小的显示单元,也是图像和界面元素的基本构成单元。每个像素都有一个唯一的坐标位置,通过X轴和Y轴的数值来确定。 屏幕的左上角是坐标原点,其坐标值为(0,0),X轴向右增加,Y轴向下增加。例如,(100, 200)表示在X轴上偏离原点100个像素,在Y轴上偏离原点200个像素,即为屏幕上的一个位置。 在Java中,可以使用Graphics类的坐标系方法绘制图像或界面元素,例如通过调用drawImage()方法可以在指定的坐标位置绘制图像。 需要注意的是,屏幕的坐标单位是相对于屏幕分辨率的,不同显示设备的分辨率可能不同,因此在编写Java程序时需要考虑不同设备的屏幕分辨率,保证界面的适配性和兼容性。 总而言之,Java中的屏幕坐标单位是像素,通过X轴和Y轴的数值来确定在屏幕上的位置,左上角为坐标原点,X轴向右增加,Y轴向下增加。在编写程序时需要考虑不同设备的分辨率,以保证界面的适配性。 ### 回答3: 在Java中,屏幕坐标单位是以像素为基础的。像素是屏幕上显示的最小单位,它代表了图像上的一个点。在Java中,屏幕坐标的原点通常位于屏幕的左上角,x轴向右延伸,y轴向下延伸。每个像素的坐标值由其相对于原点的位置来确定。 Java提供了一些类和方法来使用屏幕坐标单位。例如,java.awt包中的Graphics类和Graphics2D类提供了绘制图形和文本的方法,这些方法使用的参数就是以像素为单位的坐标值。通过这些方法,我们可以在屏幕上绘制直线、矩形、圆形等各种图形。 除了绘图,屏幕坐标单位还广泛应用于用户界面设计和图形计算等领域。在用户界面设计中,我们可以使用像素单位来指定窗口的大小、按钮的位置等,这样可以精确地控制界面元素的布局。在图形计算中,我们可以使用像素单位来进行图像处理、图像变换等操作,这样可以方便地对图像进行像素级别的操作。 总之,Java的屏幕坐标单位是以像素为基础的,通过使用像素单位,我们可以在屏幕上进行图形绘制、界面设计和图像处理等各种操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值