嘛,都刷一遍好辣。
矩阵 Am∗n 就是一个m行n列的数表。
考虑矩阵的乘法:
C=A∗B=∑aik∗bkj
那么对于矩阵A的要求就是:A为m * n的矩阵
对于矩阵B的要求就是:B为n * p的矩阵
乘得的矩阵C的规模:m * p的矩阵
矩阵乘法是不满足交换律的。但它满足结合律和分配律。
经典题目1 给定n个点,m个操作,构造O(m+n)的算法输出m个操作后各点的位置。操作有平移、缩放、翻转和旋转
然后盗图
考虑实际上这个变换对应着一个类似于线性变换的东西,我们显然是可以用矩阵来搞的。
而对于翻转,旋转和缩放都是线性变换。
然而这里冒出一个平移。。
来想一想,发现肯定是多一维常量,这样就好了。
我们考虑一个向量 a⃗ 经过矩阵的变换:
a⃗ =OPi∗a⃗
考虑这个矩阵的操作次序,一定是需要 左乘。
先翻转再平移和先平移再翻转肯定是不一样的。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
#define PI M_PI
using namespace std;
int n,m;
struct Mat{
double a[4][4];}p[10005];
Mat operator*(Mat w,Mat ww)
{
Mat c;
Rep(i,3)Rep(j,3)c.a[i][j] = 0;
Rep(i,3)Rep(k,3)Rep(j,3)c.a[i][j] += w.a[i][k] * ww.a[k][j];
return c;
}
int main ()
{
scanf("%d%d",&n,&m);
Rep(i,n)
scanf("%lf%lf",&p[i].a[1][1],&p[i].a[2][1]),p[i].a[3][1] = 1.0;
Mat res;
Rep(i,3)Rep(j,3)res.a[i][j] = (i == j);
Rep(i,m)
{
getchar();
char op;
scanf("%c",&op);
Mat ori;
Rep(i,3)Rep(j,3)ori.a[i][j] = (i == j);
if(op == 'M')
{
double x,y;
scanf("%lf%lf",&x,&y);
ori.a[1][3] = x;ori.a[2][3] = y;
}
else if(op == 'X')ori.a[2][2] = -1;
else if(op == 'Y')ori.a[1][1] = -1;
else if(op == 'S'){
double S;scanf("%lf",&S);ori.a[1][1] = ori.a[2][2] = S;}
else
{