http://acm.nyist.net/JudgeOnline/problem.php?pid=298
![NYOJ 298 点的变换 矩阵乘法 - 拟南芥 - 鲸头鹳](http://img0.ph.126.net/PjvEazSWWZqMs9wNgIZIoA==/6632562002003731542.png)
最好还是自己手推一下矩阵式子..不算太难..但是有一些小知识....
首先当然是矩阵的细节..矩阵是不支持交换率的..所以如图的式子乘进去时要放在左边...
还有的比如说:
cmath里的sin函数用的是弧度制..需要把度数/180*M_PI ( M_PI是cmath里定义的常数π );
double在取固定小数位的时候小负数四舍五入会出现-0.0之类的情况,可以自己const一个小数eps加上去.
代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=10010; 9 const double eps=1e-8; 10 int n,m; 11 double a[maxn][2]={}; 12 double b[5][5]={};//初始 13 double c[5][5]={};//添加 14 double e[5][5]={};//结束 15 void doit(int k){ 16 if(k==1){ 17 for(int i=1;i<=3;i++){ 18 for(int j=1;j<=3;j++){ 19 b[i][j]=c[i][j]; 20 } 21 } 22 }else{ 23 memset(e,0,sizeof(e)); 24 for(int i=1;i<=3;i++){ 25 for(int j=1;j<=3;j++){ 26 for(int w=1;w<=3;w++){ 27 e[i][j]+=c[i][w]*b[w][j]; 28 } 29 } 30 } 31 for(int i=1;i<=3;i++){ 32 for(int j=1;j<=3;j++){ 33 b[i][j]=e[i][j]; 34 } 35 } 36 } 37 } 38 int main(){ 39 scanf("%d%d",&n,&m); 40 for(int i=1;i<=n;i++){ 41 scanf("%lf%lf",&a[i][0],&a[i][1]); 42 }double x,y; 43 for(int i=1;i<=m;++i){ 44 memset(c,0,sizeof(c)); 45 char ch; 46 scanf("%s",&ch); 47 if(ch=='M'){ 48 scanf("%lf%lf",&x,&y); 49 c[1][1]=1.0;c[2][2]=1.0; 50 c[3][3]=1.0;c[1][3]=x;c[2][3]=y; 51 }else if(ch=='X'){ 52 c[1][1]=1.0;c[2][2]=-1.0;c[3][3]=1.0; 53 }else if(ch=='Y'){ 54 c[1][1]=-1.0;c[2][2]=1.0;c[3][3]=1.0; 55 }else if(ch=='S'){ 56 scanf("%lf",&x); 57 c[1][1]=x;c[2][2]=x;c[3][3]=1.0; 58 }else{ 59 scanf("%lf",&x); 60 c[1][1]=cos(x/180*M_PI);c[1][2]=-sin(x/180*M_PI); 61 c[2][1]=sin(x/180*M_PI);c[2][2]=cos(x/180*M_PI); 62 c[3][3]=1.0; 63 } 64 doit(i); 65 } 66 for(int i=1;i<=n;i++){ 67 x=a[i][0]*b[1][1]+a[i][1]*b[1][2]+1*b[1][3]; 68 y=a[i][0]*b[2][1]+a[i][1]*b[2][2]+1*b[2][3]; 69 printf("%.1f %.1f ",x+eps,y+eps); 70 } 71 return 0; 72 }