不知道自己算不算想複雜了,我把方塊圖案抽象成一個稱爲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;
}