题目地址:NYOJ 298
思路:该题假设用对每一个点模拟的操作。时间复杂度为O(n+m),结果肯定超时。然而利用矩阵乘法能够在O(m)的时间内把全部的操作合并为一个矩阵,然后每一个点与该矩阵相乘能够得出终于的位置。
PS:十个利用矩阵乘法解决的经典题目 超级具体。
#include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream> #include <sstream> #include <algorithm> #include <set> #include <queue> #include <stack> #include <map> using namespace std; typedef long long LL; const int inf=0x3f3f3f3f; const double pi= acos(-1.0); const double esp=1e-6; const int maxn=1e5+10; struct node { double mp[5][5]; } q[maxn],res,init,ans; struct node Mul(struct node x,struct node y) { struct node tmp; int i,j,k; for(i=0; i<3; i++) { for(j=0; j<3; j++) { tmp.mp[i][j]=0; for(k=0; k<3; k++) tmp.mp[i][j]=tmp.mp[i][j]+x.mp[i][k]*y.mp[k][j]; } } return tmp; } int main() { int n,m,i,j; double a,b,bs,jd,hd; while(~scanf("%d %d",&n,&m)) { for(i=0; i<n; i++) { scanf("%lf %lf",&q[i].mp[0][0],&q[i].mp[1][0]); q[i].mp[2][0]=1; } for(i=0; i<3; i++) { ans.mp[i][i]=1; } char str[10]; while(m--) { memset(str,0,sizeof(str)); memset(res.mp,0,sizeof(res.mp)); scanf("%s",str); for(i=0; i<3; i++) res.mp[i][i]=1; if(str[0]=='M') { scanf("%lf %lf",&a,&b); res.mp[0][2]=a; res.mp[1][2]=b; } else if(str[0]=='X') { res.mp[1][1]=-1; } else if(str[0]=='Y') { res.mp[0][0]=-1; } else if(str[0]=='S') { scanf("%lf",&bs); res.mp[0][0]=bs; res.mp[1][1]=bs; } else if(str[0]=='R') { scanf("%lf",&jd); hd=jd/180*pi; res.mp[0][0]=cos(hd); res.mp[0][1]=-sin(hd); res.mp[1][0]=sin(hd); res.mp[1][1]=cos(hd); } ans=Mul(res,ans); } for(i=0; i<n; i++) { init=Mul(ans,q[i]); printf("%.1lf %.1lf ",init.mp[0][0],init.mp[1][0]); } } return 0; }