Feed Ratios(康托展開 )

來源:互聯網
上載者:User

標籤:

Magic Squares
IOI‘96

Following the success of the magic cube, Mr. Rubik invented its planar version, called magic squares. This is a sheet composed of 8 equal-sized squares:

1 2 3 4
8 7 6 5

In this task we consider the version where each square has a different color. Colors are denoted by the first 8 positive integers. A sheet configuration is given by the sequence of colors obtained by reading the colors of the squares starting at the upper left corner and going in clockwise direction. For instance, the configuration of Figure 3 is given by the sequence (1,2,3,4,5,6,7,8). This configuration is the initial configuration.

Three basic transformations, identified by the letters `A‘, `B‘ and `C‘, can be applied to a sheet:

  • ‘A‘: exchange the top and bottom row,
  • ‘B‘: single right circular shifting of the rectangle,
  • ‘C‘: single clockwise rotation of the middle four squares.

Below is a demonstration of applying the transformations to the initial squares given above:

A:
8 7 6 5
1 2 3 4
B:
4 1 2 3
5 8 7 6
C:
1 7 2 4
8 6 3 5

All possible configurations are available using the three basic transformations.

You are to write a program that computes a minimal sequence of basic transformations that transforms the initial configuration above to a specific target configuration.

PROGRAM NAME: msquareINPUT FORMAT

A single line with eight space-separated integers (a permutation of (1..8)) that are the target configuration.

SAMPLE INPUT (file msquare.in)
2 6 8 4 5 7 3 1 
OUTPUT FORMAT
Line 1: A single integer that is the length of the shortest transformation sequence.
Line 2: The lexically earliest string of transformations expressed as a string of characters, 60 per line except possibly the last line.
SAMPLE OUTPUT (file msquare.out)
7BCABCCB
題意:一塊模板有三種操作:分別是A、B、C,A操作時交換上下兩行,B操作時將最後一列插在最前面,C操作時將中間四個數順時針旋轉一下。告訴你初始狀態和目標狀態,求最少多少次操作可以變化到目標狀態,並且輸出其操作序列。輸入的目標狀態時按順時針輸入的。

思路:
就是 BFS咯。
對於判重 下面用的是map直接暴力判斷。另外一種way就是 康托展開 得到一個Hash值。
看這個值出現過沒有就OK了。
用康托展開 不僅把空間縮小到了 n!(n為字串長度,這裡是8) 而且還很快也。
推薦~

至於康托展開:
X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! ,(其中a[i]為當前未出現的元素中是排在第幾個(從0開始))(網上十分複雜的說法)
(其實就是 比當前位置的數 小&&未出現過 的數 一共有多少個)(實質就是 在全排列中 比當前排列小的一共有多少個 )。這就是康托展開。 (將Hash值+1 就是這個排列自己的序號了(是第幾小)(從1開始))
Contor 代碼:
const int FRAC[MSQUARE_SIZE]= {1, 1, 2, 6, 24, 120, 720, 5040};//這個數組儲存的是 各個上述的 階層
//此處預設字串長度就是8
inline int Contor(string &v){ int ans = 0; for (int i = 0; i < 8; i++) { int tmp = 0; for (int j = i+1; j < 8; j++) if (v[i] > v[j]) ++tmp;
    //統計比當前位置的數 小&&未出現過的數 有多少個。
    //當然也就等於 在當前位置後面 比當前位置的數 小的數的個數
ans += tmp * FRAC[7-i]; } return ans+1;}

 

下面是題目代碼 :

/*ID:Andy ChenLANG: C++PROG: msquare*/#include<iostream>#include<cstdio>#include<queue>#include<string>#include<map>#define MAXN 10000using namespace std;struct state{    string s,ans;    int step;};char ans[MAXN];map<string,bool> vis;string tail;string opA(string a){    int i;    for(i=0;i<4;i++) swap(a[i],a[i+4]);    return a;}string opB(string a){    char t;    t=a[3];a[3]=a[2];a[2]=a[1];a[1]=a[0];a[0]=t;    t=a[7];a[7]=a[6];a[6]=a[5];a[5]=a[4];a[4]=t;    return a;}string opC(string a){    char t;    t=a[1];a[1]=a[5];a[5]=a[6];a[6]=a[2];a[2]=t;    return a;}void BFS(){    bool flag;    state t,tt;    t.step=0;t.s="12348765";t.ans="";    queue<state>Q;    Q.push(t);    vis[t.s]=true;    while(!Q.empty())//以下的vis 可以替換為 康托展開的Hash值.判斷     {        t=Q.front();Q.pop();        if(t.s==tail)        {            cout<<t.step<<endl<<t.ans<<endl;            return ;        }        tt.ans=t.ans;        tt.step=t.step+1;        flag=false;        tt.s=opA(t.s);        if(!vis[tt.s])        {            vis[tt.s]=true;            tt.ans+=‘A‘;            Q.push(tt);            flag=true;        }        tt.s=opB(t.s);        if(!vis[tt.s])        {            vis[tt.s]=true;            if(!flag) tt.ans+=‘B‘;            else tt.ans[t.step]=‘B‘;            Q.push(tt);            flag=true;        }        tt.s=opC(t.s);        if(!vis[tt.s])        {            vis[tt.s]=true;            if(!flag) tt.ans+=‘C‘;            else tt.ans[t.step]=‘C‘;            Q.push(tt);        }    }}int main(){    freopen("msquare.in","r",stdin);    freopen("msquare.out","w",stdout);    int i;    string t;    for(i=1;i<=8;i++)    {        cin>>t;tail+=t;    }    swap(tail[4],tail[7]);    swap(tail[5],tail[6]);//因為是順時針輸入,所以需要手動交換一下位置。     BFS();    return 0;}

 

Feed Ratios(康托展開 )

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.