數學建模那確實是很重要滴呀!USACO Solution Code(4):Transformations

不知道自己算不算想複雜了,我把方塊圖案抽象成一個稱爲myDraft的模型出來。第一步是將符號化的圖案抽象成10構成的矩陣,當然這一步很容易想到,然後,在這個矩陣的基礎上,將每一行和每一列看成是一系列的比特位,假設某一行是@-@---,第一步就是將其轉化成: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àRowvector中元素位置不變,元素值進行myNegate()轉換。

myNegate是什麼意思呢?我是受到了彙編語言裏面的循環移位(RORROL)的啓發。舉個例子來說,就是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;

}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章