time limit: 2 second
memory limit: 32 mb
給定 2*n 個方格,將其排成一行。選擇兩個相鄰的方格,設定為空方格,初始時不放錢幣。而其餘的方格共放入 n-1 枚金幣和 n-1 枚銀幣,每個方格恰好放入1枚錢幣。
平移操作:相鄰的兩個非空方格中的錢幣可以平行移動到兩個相鄰的空方格中,但不能改變這兩枚錢幣的排列順序。
金幣變換問題要求用最少移動次數將所有金幣移到所有銀幣的左邊。
程式設計任務:對於給定的 n-1 枚金幣和 n-1 枚銀幣的初始排列,設計乙個分支限界法,計算滿足要求的最少移動次數。
第一行有乙個正整數 t ,表示有 t 組測試資料。每組測試資料報括兩行,第一行是乙個整數 n ,第二行是 n-1 枚金幣,n-1 枚銀幣和兩個空方格的初始排列,字母 a 表示金幣,字母 b 表示銀幣,字元『.』表示空方格。。
輸入資料保證初始排列中,兩個空方格是相鄰的。0 ≤ t ≤ 100,2 ≤ n ≤ 10。
對於每組測試資料,輸出一行乙個整數,表示最少需要移動的次數;如果無解,請輸出一行「no solution」。
33abab..
5abba..abab
6a..babbababa
no solution34
初始: abba..abab【題解】第一步:abbabaa..b
第二步:a..abaabbb
第三步:aaaab..bbb
達到目標,所有的a都在b左邊。
這就是3步的解法。
c++黨直接用map來判重就可以了。
我用的是字典樹。字典樹可以作為另類的"map".就是變成訪問一條路徑而已。
用鍊錶來建樹。因為只有3個字元'a','b','.',所以在結構體中只要開3個位置就好。
然後新的指標。其下乙個一定要改為null。不然會出錯(有時候不是null)。
然後輸入多個字元的時候,不要用cin,而應該用scanf,然後再轉成string類進行操作。
在廣搜的佇列中,要記錄點號的位置,不然每次都要重新找一遍,很費時。
如果用暴力的hash去做。最後乙個點會超時。
a全部在b左邊的情況可以預處理出來。
【**】
#include #include #include using namespace std;int t,n;
struct node //用來建樹的指標
;struct data //這是佇列所記錄的內容
;node *root1,*root2; //root1是由廣搜更新出的狀態。root2記錄的是目標狀態
data team[1000000];//佇列開到100w
bool add_tree(node *root,string s) //把字串s加入到某個樹中(roo1 或 root2)
else
p = p->next[t]; //否則就順著路往下走
} return flag; //返回有沒有出現過這個字串
}void ex_change(char &a,char &b) //交換a和b兩個字元
bool bfs(string s,int kongge) //bfs設計成bool型,便於判斷有沒有解 }}
} } return false;//返回無解
}void input_data()
int p = s.find('.',0);//找到初始狀態點號的位置。
add_tree(root1,s);
if (add_tree(root2,s))
if (!bfs(s,p))
printf("no solution\n");
}}int main()
hdu 1284 錢幣兌換問題
problem description 在乙個國家僅有1分,2分,3分硬幣,將錢n兌換成硬幣有很多種兌法。請你程式設計序計算出共有多少種兌法。input 每行只有乙個正整數n,n小於32768。output 對應每個輸入,輸出兌換方法數。sample input 2934 12553 sample ...
HDU 1248 錢幣兌換問題
在乙個國家僅有1分,2分,3分硬幣,將錢n兌換成硬幣有很多種兌法。請你程式設計序計算出共有多少種兌法。input 每行只有乙個正整數n,n小於32768。output 對應每個輸入,輸出兌換方法數。sample input 2934 12553sample output 718831 1313776...
HDOJ 1284 錢幣兌換問題
problem description在乙個國家僅有1分,2分,3分硬幣,將錢n兌換成硬幣有很多種兌法。請你程式設計序計算出共有多少種兌法。input每行只有乙個正整數n,n小於32768。output對應每個輸入,輸出兌換方法數。sample input 2934 12553 sample out...