C翻转-详细解答
C翻转
http://www.nowcoder.com/questionTerminal/74bdb725421c4f80b4aca7266818baf0
思路
- 比较明显的坐标变换问题,可以把问题转换为若干个点绕某一个定点进行顺时针或者逆时针旋转,求其旋转后的坐标
- 比如样例中,以(1,1)为左上角,顺时针旋转3X3方阵,求旋转之后的矩阵。事实上,只需要对这个局部3X3方阵中的所有点进行旋转即可,其他位置的数不必动。旋转中心根据左上角坐标以及旋转半径很容易求出来,然后套公式计算旋转之后的位置坐标即可。
核心数学公式
任意点(x,y),绕一个坐标点(rx,ry)逆时针旋转a角度后的新的坐标设为(x0, y0),有公式:
注意这里a角度是逆时针,顺时针旋转时角度取负即可。因为是90度所以三角函数值无非就是1,0,自己代入手动计算一下。证明的话在纸上画一下坐标系,根据三角函数关系不难推算。
代码
#include<iostream> #include<queue> #include<list> #include<vector> #include<cstring> #include<set> #include<stack> #include<map> #include<cmath> #include<algorithm> #include<string> #include<stdio.h> using namespace std; typedef long long ll; int main(){ int num[10][10]; int bak[10][10]; int a,b,x,y; while(cin>>num[1][1]){ //多组样例输入 for(int i=2;i<6;i++) cin>>num[1][i]; for(int i=2; i<6; i++){ for(int j=1; j<6; j++){ cin>>num[i][j]; } } //接收左上角坐标以及旋转方式 旋转块大小 cin>>a>>b>>x>>y; for(int i=1; i<6; i++){ for(int j=1; j<6; j++){ if(i>=x && i<x+b && j>=y && j<y+b){ //若该点在旋转方阵区域内 if(a == 2){ //逆时针旋转 int x0 = x + y - j + b - 1; int y0 = i - x + y; bak[x0][y0] = num[i][j]; // } else{ //顺时针旋转 int x0 = j - y + x; int y0 = x + y + b - i - 1; bak[x0][y0] = num[i][j]; } } else{ //外部点不动 bak[i][j] = num[i][j]; } } } for(int i=1; i<6; i++){ for(int j=1; j<6; j++){ if(j != 1) cout<<" "; cout<<bak[i][j]; } cout<<endl; } } return 0; }