当前位置: 首页 > news >正文

UVa1497/LA5719 A Letter to Programmers

UVa1497/LA5719 A Letter to Programmers

  • 题目链接
  • 题意
  • 分析
    • 一个坑点
  • AC 代码

题目链接

  本题是2011年icpc亚洲区预赛北京赛区的G题

题意

  空间里有 n(n≤1 000)个点,你的任务是执行一段程序,输出程序运行结束后所有点的坐标。一共有 5 条指令,如下表所示。

指令说 明
translate tx ty tz所有点(x,y,z)移动到(x+tx,y+ty,z+tz)
scale a b c所有点(x,y,z)移动到(ax,by,cz)
rotate a b c d所有点旋转。旋转轴是(0,0,0)-(a,b,c),旋转角度是d 度。如果你站在(a,b,c)并且面朝(0,0,0),旋转呈逆时针
repeat k和 end 配对,二者之间的指令重复执行k 次。k 为32 位带符号整数。注意 repeat 和 end 之间可以嵌套 repeat。
end和 repeat 指令配对或者作为程序终止

  程序不超过100 行,除了n 和k 之外所有参数的绝对值均不超过1 000。

分析

  按题意构造平移、缩放、旋转三种变换矩阵(可以参考三维仿射变换矩阵),将所有变换矩阵乘起来得到最终的变换矩阵,然后对每个输入点计算出答案即可。注意处理 repeat 需要用矩阵快速幂计算加速。

一个坑点

  题目说输出坐标的结果四舍五入到小数点第二位,我用 io manipulator 来控制小数点,但由于运算过程中三角函数等带来的精度损失,坐标值都加上 1e-6 才 AC 的。

AC 代码

#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;int n, t; const double e = M_PI/180.; char s[10]; double a[4][4], p[4][4], c[4][4], r[52][4][4];void identity_mat(double (&t)[4][4]) {for (int i=0; i<4; ++i) for (int j=0; j<4; ++j) t[i][j] = i==j ? 1. : 0.;
}void trans_mat(double tx, double ty, double tz, double (&t)[4][4]) {identity_mat(t); t[0][3] = tx; t[1][3] = ty; t[2][3] = tz;
}void scale_mat(double a, double b, double c, double (&t)[4][4]) {identity_mat(t); t[0][0] = a; t[1][1] = b; t[2][2] = c;
}void rot_mat(double a, double b, double c, double d, double (&t)[4][4]) {double s = sqrt(a*a + b*b + c*c); a /= s; b /= s; c /= s; d *= e;double co = cos(d), si = sin(d), c1 = 1.-co; identity_mat(t);t[0][0] = co + a*a*c1; t[0][1] = a*b*c1 - c*si; t[0][2] = a*c*c1 + b*si;t[1][0] = a*b*c1 + c*si; t[1][1] = co + b*b*c1; t[1][2] = b*c*c1 - a*si;t[2][0] = a*c*c1 - b*si; t[2][1] = b*c*c1 + a*si; t[2][2] = co + c*c*c1;
}void copy(const double (&a)[4][4], double (&b)[4][4]) {for (int i=0; i<4; ++i) for (int j=0; j<4; ++j) b[i][j] = a[i][j];
}void mat_mul(const double (&a)[4][4], const double (&b)[4][4], double (&c)[4][4]) {for (int i=0; i<4; ++i) for (int j=0; j<4; ++j) {c[i][j] = 0.;for (int k=0; k<4; ++k) c[i][j] += a[i][k]*b[k][j];}
}void mat_pow(const double (&x)[4][4], int y, double (&b)[4][4]) {identity_mat(b); copy(x, p);while (y) {if (y & 1) mat_mul(b, p, a), copy(a, b);if (y >>= 1) mat_mul(p, p, a), copy(a, p);}
}void dfs(int k = -1) {while (true) {cin >> s;if (s[0] == 'r' && s[1] == 'e') {int k1; cin >> k1; identity_mat(r[++t]); dfs(k1);} else if (s[0] == 'e') {if (k >= 0) mat_pow(r[t], k, c), mat_mul(c, r[--t], a), copy(a, r[t]);return;} else {if (s[0] == 't') {double x, y, z; cin >> x >> y >> z; trans_mat(x, y, z, c);} else if (s[0] == 's') {double x, y, z; cin >> x >> y >> z; scale_mat(x, y, z, c);} else {double x, y, z, d; cin >> x >> y >> z >> d; rot_mat(x, y, z, d, c);}mat_mul(c, r[t], a); copy(a, r[t]);}}
}void solve() {identity_mat(r[t=0]); dfs();while (n--) {double x, y, z; cin >> x >> y >> z;cout << r[0][0][0]*x + r[0][0][1]*y + r[0][0][2]*z + r[0][0][3] + 1e-6 << ' ' << r[0][1][0]*x + r[0][1][1]*y + r[0][1][2]*z + r[0][1][3] + 1e-6 << ' ' << r[0][2][0]*x + r[0][2][1]*y + r[0][2][2]*z + r[0][2][3] + 1e-6 << endl;}cout << endl;
}int main() {cout << fixed << setprecision(2);while (cin >> n && n) solve();return 0;
}
http://www.dtcms.com/a/519633.html

相关文章:

  • 谷歌Quantum Echoes算法:迈向量子计算现实应用的重要一步
  • 网络管理员教程(初级)第六版--第2章 局域网技术
  • PY32F040单片机介绍(1)
  • 数据库多表关系、查询与约束
  • 空调设备公司网站建设建设部网站社保联网
  • 济源网站建设电话锦州做网站的个人
  • 逻辑推演题——谁是骗子
  • 单位网站建设汇报材料wordpress菜单保存不
  • 【底层机制】【Android】Android 系统的启动流程
  • js基础:06、函数(创建函数、参数、返回值、return、立即执行函数、对象(函数))和枚举对象的属性
  • LeetCode 刷题【131. 分割回文串】
  • 7. Functions(函数)
  • 零基础掌握 Vanna Text2SQL 框架:从原理到实战训练指南
  • [linux仓库]信号处理及可重入函数[进程信号·陆]
  • webrtc源码走读(一)-QOS-NACK-概述
  • wordpress 企业网站 免费如何注册网站免费的
  • 斗地主游戏源码,自适应手机版,带有管理后端
  • Linux桌面X11服务-XRecord方案捕获鼠标点击的应用窗口
  • 021数据结构之并查集——算法备赛
  • 网站制作售后免费在线代理网站
  • Vue组件的一些底层细节
  • 2. =>的用法 C#例子 WPF例子
  • 在C#中出现WinForm原控件Chart卡顿问题
  • Spring Boot 3零基础教程,WEB 开发 内嵌服务器底层源码分析 笔记48
  • 网站开发案例分析成都制作网页
  • 导入的 Google(Chrome)书签默认不会自动显示在「书签栏」,而是放在一个文件夹里。下面是详细步骤,帮你把 导入的全部书签添加到书签栏
  • 一小时内使用NVIDIA Nemotron创建你自己的Bash计算机使用智能体
  • Chrome开发者工具
  • 虚拟机 Ubuntu 中安装 Google Chrome 浏览器
  • Docker/K8s部署MySQL的创新实践与优化技巧大纲