不知道自己算不算想复杂了,我把方块图案抽象成一个称为myDraft的模型出来。第一步是将符号化的图案抽象成1和0构成的矩阵,当然这一步很容易想到,然后,在这个矩阵的基础上,将每一行和每一列看成是一系列的比特位,假设某一行是:@-@---,第一步就是将其转化成:10100,然后再将其转化成一个十进制数,即2^4+2^2=20,保存下这个值,所有的行和列都进行同样的处理,处理的结果就是myDraft了。
为什么要搞一个这样的myDraft出来呢?当然是为了拿一坨见鬼的翻转和比较的方便了。以两矩阵的比较为例,如果你每次都老老实实遍历两个矩阵的matrix[i][j]做对比,时间开销为O(n2)。进行翻转的话,需要对每个元素进行( i , j )à(n-1-j, i )的坐标转换,也是O(n2)是无法避免的。对时间效率的追求,有了myDraft。
不管你怎么旋转,都不会改变每一行/列中的1或是0——貌似是句废话,呵呵~同时更重要的是,旋转中行和列的转化是有规律的,在旋转中,只要利用这个规律相应改变蓝色部分,也就是存储在vector里面的值,就可以了。 旋转规律: l 原Rowà新Column: vector中元素位置前后倒置,元素值进行myNegate()转换; l 原Columnà新Row:vector中元素位置不变,元素值进行myNegate()转换。 myNegate是什么意思呢?我是受到了汇编语言里面的循环移位(ROR、ROL)的启发。举个例子来说,就是110变成011,说白了就是比特位的翻转。为什么要这么做,看看上面的图应该就知道了。 下面是整个程序的源代码。代码还可以优化,不过差不多是语言级的优化了吧。没细看了。总之这道题AC后觉得挺爽的,觉得自己的模型建立得比较好!建模能力确实很重要啊! /* ID: fairyroad PROG: transform LANG: C++ */ #include<fstream> #include<vector> using namespace std; ofstream fout ("transform.out"); ifstream fin ("transform.in"); /* The model of this program treats each row or column of the square pattern(myDraft) as a series of bits for example,"@-@--" is valued as 10100, which equals to 2^4+2^2=20 The input: @-@ 101 101 --- --> 000 rotate90: 100 @@- 110 001 will be stored like this: (3, (5,0,6), (5,1,4) ), after rotation: (3, (5,4,1), (6,0,5) ) Through this model,the rotation and compare will be very easy. */ struct myDraft { vector<int> row, column; // Respectively records the summary of each row or column int length; myDraft(int n) : length(n), row(n,0), column(n,0) {} myDraft(const myDraft& other) : length(other.length), row(other.row), column(other.column) {} void getInput() { int times=length; while (times) { int len=length, res=0, flag=0; char ch; while (len) { fin>>ch; flag= ch=='@'?1:0; res=(res<<1)+flag; column[length-len]= (column[length-len]<<1)+flag; --len; } row[length-times]=res; --times; } } inline myDraft rotate90() { myDraft tmp(length); //tmp.row=column; for (int i=0; i<length; i++){ tmp.column[i]=row[length-i-1]; tmp.row[i]= myNegate(column[i]); } return tmp; } myDraft rotate180() { return rotate90().rotate90(); } myDraft rotate270() { return rotate180().rotate90(); } inline myDraft flip() { myDraft tmp(*this); int guard=length>>1; int times=1, header=0, tail=length-1; //vector<int>::iterator header=tmp.column.begin(), tail= --tmp.column.end(); while (times<=guard) { int temp=tmp.column[header]; tmp.column[header]=tmp.column[tail]; tmp.column[tail]=temp; tmp.row[header]=myNegate(tmp.row[header]); tmp.row[tail]=myNegate(tmp.row[tail]); ++header; --tail; ++times; } if (header==tail) tmp.row[tail]=myNegate(tmp.row[tail]); return tmp; } inline bool operator==(const myDraft& other) { return row==other.row && column==other.column; } private: inline int myNegate(int candicate) // if the candicate is 4(100), then change it into 001 { int count=length, res=0; while(count){ int lowbit=1; lowbit&=candicate; res=(res<<1)+lowbit; candicate>>=1; --count; } return res; } }; int measure( myDraft& src, myDraft& dest) { if (src.rotate90()==dest) return 1; else if (src.rotate180()==dest) return 2; else if (src.rotate270()==dest) return 3; return 0; } int main() { int n; fin>>n; myDraft src(n), dest(n); src.getInput(); dest.getInput(); int res=measure(src, dest); if(res) {fout<<res<<endl; return 0;} else{ myDraft tmp=src.flip(); if(tmp==dest) { fout<<4<<endl; return 0; } else if(measure(tmp, dest)) { fout<<5<<endl; return 0; } } if (src==dest) { fout<<6<<endl; return 0; } fout<<7<<endl; return 0; }