POJ 1835
为了切切题,随便找了到模拟题做。虽然是模拟题,但是好像也没有那么显然。如果按照位置全部判断一下肯定是不行的。分析问题时,要从本质入手。首先要找到它的数学公式。
这是个三维空间上的问题,首先需要两个参数来表示其状态,一个是head(身体的方向),一个是face(脸的朝向)。我们要做的就是更新这两个变量。题目中用0,1,2,3,4,5来表示6个方向,这其实是一种误导,用一维表示怎么能推出数学式子呢。所以我们将face和head用向量表示。
然后考虑给的6个方向转换函数,比如left,设其转变后的向量为l,那么有l*face = 0, l * head = 0, l x face = head。这样就能够遍历6个方向,找到l。同理可以推出其他转换函数。
这题给我的启发是,从问题本质入手, 解决问题。有的时候刷题不是最重要的,就算是简单的问题,也要找到简单干净的解。最好自己动动笔。
注:写代码时候,遇到了语言问题。在函数中声明的数组变量,以指针形式返回时,将会被值栈回收,产生错误。要传数组时,可以放在参数列表中(虽然代码感觉不好)。
#include <cstdio> #include <cstring> using std::memset; //0,1,2,3,4,5 int direction[6][3] = {{1,0,0}, {0,1,0}, {0,0,1}, {-1,0,0}, {0,-1,0}, {0,0,-1}}; int head[3], face[3], position[3]; int dot(int x[3], int y[3]) { int ans = 0; for(int i = 0 ; i < 3; i++) ans += x[i]*y[i]; return ans; } bool equal(int x[3],int y[3]) { for(int i = 0 ; i < 3; i++) if(x[i] != y[i]) return false; return true; } void cross(int x[3],int y[3], int ans[3]) { ans[0] = x[1]*y[2] - x[2]*y[1]; ans[1] = x[2]*y[0] - x[0]*y[2]; ans[2] = x[0]*y[1] - x[1]*y[0]; return; } void back() { for(int i = 0 ; i < 3; i++) face[i] = -face[i]; } void left() { for(int i = 0 ; i < 6; i++) { if(dot(direction[i], head)) continue; if(dot(direction[i], face)) continue; int temp[3]; cross(direction[i], face, temp); if(equal(head, temp) == false) continue; for(int j = 0 ; j < 3; j++) face[j] = direction[i][j]; return; } } void right() { for(int i = 0 ;i < 3; i++) left(); } void up() { int temp[3]; for(int i = 0 ; i < 3; i++) temp[i] = face[i]; for(int i = 0 ; i < 3; i++) face[i] = head[i]; for(int i = 0 ; i < 3; i++) head[i] = -temp[i]; } void down() { for(int i = 0 ; i < 3; i++) up(); } int main() { int cas; scanf("%d",&cas); while(cas--) { int n; scanf("%d", &n); face[0] = 1; face[1] = 0; face[2] = 0; head[0] = 0; head[1] = 0; head[2] = 1; position[0] = 0; position[1] = 0; position[2] = 0; while(n--) { char op[10]; int x; scanf("%s%d", op, &x); switch(op[0]) { case 'l': left(); break; case 'r': right(); break; case 'f': break; case 'b': back(); break; case 'u': up(); break; case 'd': down(); break; } for(int i = 0 ; i < 3; i++) { position[i] += x * face[i]; } } for(int i = 0 ; i < 3; i++) printf("%d ", position[i]); for(int i = 0 ; i < 6; i++) { if(equal(face, direction[i])) printf("%d\n", i); } } }