時間限制: 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個正整數來表示。可以用顏色的序列來表示一種魔板狀態,規定從魔...