算法1
前缀和优化
include [HTML_REMOVED]
include [HTML_REMOVED]
include [HTML_REMOVED]
using namespace std;
const int N = 100005;
int main() {
int n, m;
cin >> n >> m;
//存储缩放因子和旋转角度的前缀和,使得在处理查询时可以快速获得所需的缩放和旋转值。
vector<double> scale(N, 1.0); // 前缀乘积,初始为1
vector<double> angle(N, 0.0); // 前缀和,初始为0
for (int i = 1; i <= n; i++) {
int type;
double value;
cin >> type >> value;
if (type == 1) {
scale[i] = scale[i - 1] * value; // 拉伸
angle[i] = angle[i - 1]; // 旋转不变
} else {
scale[i] = scale[i - 1]; // 拉伸不变
angle[i] = angle[i - 1] + value; // 累加旋转
}
}
while (m--) {
int start, end;
double x, y;
cin >> start >> end >> x >> y;
// 计算最终缩放因子和旋转角度
double totalScale = scale[end] / scale[start - 1];
double totalAngle = angle[end] - angle[start - 1];
// 应用缩放
x *= totalScale;
y *= totalScale;
// 应用旋转
double xNew = x * cos(totalAngle) - y * sin(totalAngle);
double yNew = x * sin(totalAngle) + y * cos(totalAngle);
// 输出结果
printf("%.5lf %.5lf\n", xNew, yNew);
}
return 0;
}
算法2
(暴力枚举)
include [HTML_REMOVED]
include [HTML_REMOVED]
using namespace std;
const int N = 100005;
int n, m;
double t[N][2];
void trans1(double k, double &x, double &y) {
// 拉伸操作
x = k;
y = k;
}
void trans2(double ce, double &x, double &y) {
// 旋转操作
double newX = x * cos(ce) - y * sin(ce);
double newY = x * sin(ce) + y * cos(ce);
x = newX;
y = newY;
}
int main() {
cin >> n >> m;
// 存储操作类型和参数
for (int i = 1; i <= n; i++) {
int flag;
double s;
cin >> flag >> s;
t[i][0] = flag; // 操作类型
t[i][1] = s; // 操作值
}
while (m--) {
int start, end;
double x, y;
cin >> start >> end >> x >> y;
// 在查询范围内应用操作
for (int z = start; z <= end; z++) {
if (t[z][0] == 1) // 如果是拉伸操作
trans1(t[z][1], x, y);
else // 如果是旋转操作
trans2(t[z][1], x, y);
}
// 输出结果
printf("%.5lf %.5lf\n", x, y);
}
return 0;
}