問題 1176 魔板 借鑑 注釋版

2021-10-03 09:22:05 字數 4440 閱讀 2073

時間限制: 1sec 記憶體限制: 128mb

在魔方風靡全球之後不久,rubik先生發明了它的簡化版――魔板。魔板 由8個同樣大小的方塊組成,每個方塊顏色均不相同,可用數字1-8分別表示。任一時刻魔板的狀態可用方塊的顏色序列表示:從魔板的左上角開始,按順時針方 向依次寫下各方塊的顏色代號,所得到的數字序列即可表示此時魔板的狀態。例如,序列(1,2,3,4,5,6,7,8)表示魔板狀態為:

1 2 3 4

8 7 6 5

對於魔板,可施加三種不同的操作,具體操作方法如下:

a: 上下兩行互換,如上圖可變換為狀態87654321

b: 每行同時迴圈右移一格,如上圖可變換為41236785

c: 中間4個方塊順時針旋轉一格,如上圖可變換為17245368

給你魔板的初始狀態與目標狀態,請給出由初態到目態變換數最少的變換步驟,若有多種變換方案則取字典序最小的那種。

輸入

每組測試資料報括兩行,分別代表魔板的初態與目態。

輸出

對每組測試資料輸出滿足題意的變換步驟。

樣例輸入

12345678

17245368

12345678

82754631

樣例輸出cac

注釋寫好了,也終於弄懂了

首先是設定乙個結構體,然後根據結構體定義乙個很大的佇列陣列。

先來說說這個結構的成員:str用來存放魔板資訊;opt當前魔板進行的操作;par前一步的操作在佇列中的位置

然後就是每一種情況的代表關鍵字,這個地方很巧妙,從i=0到7,計算從第i個數開始後面的數大於第i個數的個數,然後乘以對應的階乘。這個階乘的作用就是拉大vi陣列間隔的值。

通過佇列的操作,每一步後都有三種可能,使用par就將這些操作連起來。

#include

#include

#define maxn 40330

#define maxl 8

struct

queue[maxn]

, tmp, nxt;

//階乘:0 1 2 3 4 5 6 7

int fac[8]

=;//作用是什麼?

int vis[maxn]

;//訪問函式

char opt=

"abc"

;//三種選擇的陣列

char aim[maxl +1]

;//目標魔板

void

(*fun[3]

)(char

*str)

;//定義三個單位大小的指標陣列,用來存放三個變形函式的位址

//交換函式

void

swap

(char

* a,

char

* b)

//三種變形函式

void

opta

(char

* str)

void

optb

(char

* str)

str[0]

= tmp;

for(tmp = str[7]

, i =

7; i >4;

--i)

str[4]

= tmp;

}void

optc

(char

* str)

//列印輸出

void

print

(int k)

//雜湊函式

//為什麼要統計這個資料呢?或者說這個資料對檢驗重複的資料的作用是什麼?

inthash

(char

*str)

sum +

= cnt * fac[maxl - i -1]

;//累加統計的數乘以i的階乘}if

(vis[sum]

)return1;

//如果已經訪問,則返回1

vis[sum]=1

;//未訪問,則返回0,訪問

return0;

}//廣度優先遍歷

void

bfs(

)++rear;

//繼續入隊

}++front;

//出隊乙個,即前面的那種情況的後續情況已經考慮結束,接著從下一種情況開始考慮}}

intmain()

return0;

}

二維陣列

#include

#include

void

exch

(int

*a,int

*b)void

arraycpy

(int a[

5],int b[

5])int

match

(int a[

5],int b[

5])//a: 上下兩行互換,如上圖可變換為狀態87654321

//b: 每行同時迴圈右移一格,如上圖可變換為41236785

//c: 中間4個方塊順時針旋轉一格,如上圖可變換為17245368

void

change

(int a[

5],int n)

return;}

if(n==2)

}return;}

if(n==3)

}void

magic

(int a[

5],int b[

5]),opera[10]

=,flag=0;

while

(!flag)

}arraycpy

(c,a)

;for

(i=1

;i<=opera[0]

&&!flag;i++)}

}printf

("\n");

}void

stringtoint

(char s,

int a[

5])int

main()

,b[3][

5]=;

char s[8]

;//陣列0行0列空置

while

(scanf

("%s"

, s)+1

)}return0;

}

一維陣列

/*

12345678

17245368

12345678

82754631

*/#include

#include

void

exch

(int

*a,int

*b)void

arraycpy

(int a,

int b)

intmatch

(int a,

int b)

//12345678

//41236785

//17245368

//a: 上下兩行互換,如上圖可變換為狀態87654321

//b: 每行同時迴圈右移一格,如上圖可變換為41236785

//c: 中間4個方塊順時針旋轉一格,如上圖可變換為17245368

void

change

(int a,

int n)

return;}

if(n==2)

a[1]

=t;for

(i=7

,t=a[i]

;i>

4;i--

) a[5]

=t;return;}

if(n==3)

}void

magic

(int a,

int b)

,opera[10]

=;//這個地方絕對有問題

while(1

)}arraycpy

(c,a)

;for

(i=1

;i<=opera[0]

;i++)if

(match

(b,c))}

}/*12345678

1234

8765

*/void

stringtoint

(char s,

int a)

intmain()

,b[9]=

;char s[8]

;//陣列0行0列空置

while

(scanf

("%s"

, s)+1

)}return0;

}

魔板問題(搜尋)

時間限制 1 sec 記憶體限制 64 mb 提交 23 解決 6 提交 狀態 討論版 命題人 admin 題目描述 據說能使持有者成為世界之主的上古神器隱藏在魔板空間,魔板由8個同樣大小的方塊組成,每個方塊顏色均不相同,按順時針方向依次寫下各方塊的顏色代號,例如序列 1,2,3,4,5,6,7,8...

魔板問題的分析與解答

描述在成功地發明了魔方之後,魯比克先生發明了它的二維版本,稱作魔板。這是一張有8個大小相同的格仔的魔板 1 2 3 4 8 7 6 5我們知道魔板的每乙個方格都有一種顏色。這8種顏色用前8個正整數來表示。可以用顏色的序列來表示一種魔板狀態,規定從魔板的左上角開始,沿順時針方向依次取出整數,構成乙個顏...

問題 B 魔板(USACO3 2 5)

問題 b 魔板 usaco3.2.5 題目描述 在成功地發明了魔方之後,拉比克先生發明了它的二維版本,稱作魔板。這是一張有 8個大小相同的格仔的魔板 1 2 3 4 8 7 6 5 我們知道魔板的每乙個方格都有一種顏色。這 8種顏色用前 8個正整數來表示。可以用顏色的序列來表示一種魔板狀態,規定從魔...