CCF CSP 20239-2 坐标变换(其二)

问题描述

对于平面直角坐标系上的坐标 (x,y),小 P 定义了如下两种操作:

  1. 拉伸 k 倍:横坐标 x 变为 kx,纵坐标 y 变为 ky;

  2. 旋转 θ:将坐标 (x,y) 绕坐标原点 (0,0) 逆时针旋转 θ 弧度(0≤θ<2π)。易知旋转后的横坐标为 xcos⁡θ−ysin⁡θ,纵坐标为 xsin⁡θ+ycos⁡θ。

设定好了包含 n 个操作的序列 (t1,t2,⋯,tn) 后,小 P 又定义了如下查询:

  • i j x y:坐标 (x,y) 经过操作 ti,⋯,tj(1≤i≤j≤n)后的新坐标。

对于给定的操作序列,试计算 m 个查询的结果。

输入格式

从标准输入读入数据。

输入共 n+m+1 行。

输入的第一行包含空格分隔的两个正整数 n 和 m,分别表示操作和查询个数。

接下来 n 行依次输入 n 个操作,每行包含空格分隔的一个整数(操作类型)和一个实数(k 或 θ),形如 1 k(表示拉伸 k 倍)或 2 θ(表示旋转 θ)。

接下来 m 行依次输入 m 个查询,每行包含空格分隔的四个整数 i、j、x 和 y,含义如前文所述。

输出格式

输出到标准输出中。

输出共 m 行,每行包含空格分隔的两个实数,表示对应查询的结果。

样例输入

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

Data

样例输出

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

AC80

#include <bits/stdc++.h>
using namespace std;

//double sin0(double jiaodu){
//	double radians = jiaodu * M_PI / 180.0;
//	double sinValue = sin(radians);
//	return sinValue;
//}
//double cos0(double jiaodu){
//	double radians = jiaodu * M_PI / 180.0;
//	double sinValue = cos(radians);
//	return sinValue;
//}

int main(){
	int n,m;
	cin>> n>> m;
	double dx[n],dy[n];
	double x[m],y[m];
	double l[m],r[m];
//输入
	for(int i=0;i<n;i++){
		cin>>dx[i]>>dy[i];
	}
	for(int i=0;i<m;i++){
		cin>>l[i]>>r[i]>>x[i]>>y[i];
	}
	
	
	for(int i=0;i<m;i++){
	double lashen=1,xuanzhuan=0;
		
		//进行操作
		for(int j=l[i]-1;j<r[i];j++){
			if(dx[j]==1){
				lashen=lashen*dy[j];
			}
			else{
				xuanzhuan+=dy[j];
//				double xx=x[i];
//			    double yy=y[i];
//				x[i]=xx*cos((-1)*dy[j])-yy*sin((-1)*dy[j]);
//				y[i]=xx*cos((-1)*dy[j])+yy*sin((-1)*dy[j]);
			}
			
		}
		x[i]*=lashen;
		y[i]*=lashen;
//		double xx=x[i];
//		double yy=y[i];
//		x[i]=x[i]*cos(xuanzhuan)-y[i]*sin(xuanzhuan);
//		y[i]=x[i]*cos(xuanzhuan)+y[i]*sin(xuanzhuan);

	cout << fixed << setprecision(3) << x[i]*cos(xuanzhuan)-y[i]*sin(xuanzhuan) << " " << x[i]*sin(xuanzhuan)+y[i]*cos(xuanzhuan) << endl;
	}
		
	//for(int j=0;j<m;j++) cout << x[j] << " " << y[j] << endl;
//	for(int j = 0; j < m; j++) {
//		cout << fixed << setprecision(3) << x[j] << " " << y[j] << endl;
//	}
	
	
	return 0;
	
}


优化一下(还是80)超时了

#include <bits/stdc++.h>
using namespace std;


int main(){
	int n,m;
	cin>> n>> m;

	double dx[n],dy[n];
	double x[m],y[m];
	double l[m],r[m];
//输入
	for(int i=0;i<n;i++){
		cin>>dx[i]>>dy[i];
	}
	for(int i=0;i<m;i++){
		cin>>l[i]>>r[i]>>x[i]>>y[i];
		double lashen=1,xuanzhuan=0;
		for(int j=l[i]-1;j<r[i];j++){
			if(dx[j]==1){
				lashen=lashen*dy[j];
			}
			else{
				xuanzhuan+=dy[j];

			}
			
		}
		x[i]*=lashen;
		y[i]*=lashen;

		
		cout << fixed << setprecision(3) << x[i]*cos(xuanzhuan)-y[i]*sin(xuanzhuan) << " " << x[i]*sin(xuanzhuan)+y[i]*cos(xuanzhuan) << endl;

		
	}
	
	

	return 0;
	
}


 AC题解使用了动态数组

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n, m;
	cin >> n >> m;
	//用vector来使用动态数组
	vector<double> a(n+1);
	vector<double> b(n+1);
	for (int i = 1; i <= n; i++)
	{
		int x;
		cin >> x;
		if (x == 1)
		{
			cin >> a[i];
			b[i] = 0;
		}
		else
		{
			cin >> b[i];
			a[i] = 1;
		}
	}
	vector<double> sum1(n+2), sum2(n+2);
	sum1[0] = 1;
	sum2[0] = 0;
	//直接计算前缀和(根据递推关系式直接求解)
	for (int i = 1; i <=n; i++)
	{
		sum1[i] = a[i] * sum1[i - 1];
		sum2[i] = b[i] + sum2[i - 1];
	}
	//根据所给公式计算m次的结果
	for (int i = 0; i < m; i++)
	{
		int start, end;
		double x, y;
		cin >> start >> end >> x >> y;
		double k = sum1[end] / sum1[start - 1];
		double theta = sum2[end] - sum2[start - 1];
		x = x * k;
		y = y * k;
		double temp = x;
		x = x * cos(theta) - y * sin(theta);
		y = temp * sin(theta) + y * cos(theta);
		printf("%.3lf %.3lf\n", x, y);
	}
	return 0;
}

提交如下 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值