您的位置:首页 > 其它

2011 ACM/ICPC 北京赛区现场赛解题:ALetter to Programmers

2011-11-13 22:01 495 查看
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4087

题目和裸的一道题,当时貌似我们也带了矩阵操作的模板,不过因为卡A和B所以没做,今天抽出了时间做了一下。

矩阵三种操作:

平移

translate tx ty tz

1 0 0 tx

0 1 0 ty

0 0 1 tz

0 0 0 1

缩放

scale kx ky kz

kx 0 0 0

0 ky 0 0

0 0 kz 0

0 0 0 1

绕任意轴(过原点)旋转(要把轴向量归一化,不然会在“点在轴上”这个情况下出问题)

rotate x y z d

(1-cos(d))*x*x+cos(d) (1-cos(d))*x*y-sin(d)*z (1-cos(d))*x*z+sin(d)*y 0

(1-cos(d))*y*x+sin(d)*z (1-cos(d))*y*y+cos(d) (1-cos(d))*y*z-sin(d)*x 0

(1-cos(d))*z*x-sin(d)*y (1-cos(d))*z*y+sin(d)*x (1-cos(d))*z*z+cos(d) 0

一个trick,就是正常写法会出现-0.0这个解,必须手动修改偏差.....

我的代码太丑了....粘R叔的吧。

代码:

#include <iostream>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <stack>
#include <cmath>
#define rep(i, j, k) for (int (i) = (j); (i) < (k); ++(i))
using namespace std;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int maxn = 1005;

int sgn(double x)
{
return x < -eps ? -1 : x > eps;
}

struct matrix
{
int r, c;
double v[5][5];
matrix(){}
matrix(int a, int b) : r(a), c(b)
{
rep(i, 0, r)
fill(v[i], v[i] + c, 0.0);
if (r == c)
{
rep(i, 0, r)
v[i][i] = 1.0;
}
}
matrix operator *(const matrix p)
{
matrix ans(r, p.c);
rep(i, 0, r)
rep(j, 0, ans.c)
{
double tmp = 0.0;
rep(k, 0, c)
tmp += v[i][k] * p.v[k][j];
ans.v[i][j] = tmp;
}
return ans;
}
};

matrix power(matrix a, int n)
{
matrix e(a.c, a.c);
if (n == 0)
return e;
matrix ans = power(a, n / 2);
ans = ans * ans;
return (n % 2) ? ans * a : ans;
}

struct point
{
double x, y, z;
point(){}
point(double a, double b, double c) : x(a), y(b), z(c){}
void in()
{
scanf("%lf%lf%lf", &x, &y, &z);
}
void print()
{
printf("%.2lf %.2lf %.2lf\n", x + eps, y + eps, z + eps);
}
} p[maxn];

int n;

point fuck(point now, matrix a)
{
matrix o(4, 1);
o.v[0][0] = now.x;
o.v[1][0] = now.y;
o.v[2][0] = now.z;
o.v[3][0] = 1.0;
matrix ans = a * o;
return point(ans.v[0][0], ans.v[1][0], ans.v[2][0]);
}

char op[20];

matrix dfs(int times)
{
matrix ans(4, 4);
double v[5];
int what;
while (scanf("%s", op) == 1)
{
matrix temp(4, 4);
if (op[0] == 'e')
break;
else
if (op[0] == 'r')
{
if (op[1] == 'e')
{
scanf("%d", &what);
temp = dfs(what);
}
else
{
rep(i, 0, 4)
scanf("%lf", &v[i]);
double l = 0.0;
rep(i, 0, 3)
l += v[i] * v[i];
l = sqrt(l);
v[3] = v[3] / 180.0 * pi;
double ct = cos(v[3]), st = sin(v[3]);
rep(i, 0, 3)
v[i] /= l;
temp.v[0][0] = (1.0 - ct) * v[0] * v[0] + ct;
temp.v[0][1] = (1.0 - ct) * v[0] * v[1] - st * v[2];
temp.v[0][2] = (1.0 - ct) * v[0] * v[2] + st * v[1];
temp.v[1][0] = (1.0 - ct) * v[1] * v[0] + st * v[2];
temp.v[1][1] = (1.0 - ct) * v[1] * v[1] + ct;
temp.v[1][2] = (1.0 - ct) * v[1] * v[2] - st * v[0];
temp.v[2][0] = (1.0 - ct) * v[2] * v[0] - st * v[1];
temp.v[2][1] = (1.0 - ct) * v[2] * v[1] + st * v[0];
temp.v[2][2] = (1.0 - ct) * v[2] * v[2] + ct;
}
}
else
if (op[0] == 't')
{
rep(i, 0, 3)
{
scanf("%lf", &v[i]);
temp.v[i][3] = v[i];
}
}
else
if (op[0] == 's')
{
rep(i, 0, 3)
{
scanf("%lf", &v[i]);
temp.v[i][i] = v[i];
}
}
ans = temp * ans;
}
return power(ans, times);
}

int main()
{
while (scanf("%d", &n) == 1 && n)
{
matrix temp(4, 4);
temp = dfs(1) * temp;
for (int i = 0; i < n; ++i)
{
p[i].in();
p[i] = fuck(p[i], temp);
p[i].print();
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: