Vijos P1016 鐘錶問題 BFS 剪枝

2021-07-09 11:25:14 字數 1522 閱讀 9313

vijos p1016

九個鐘錶分別有4種狀態  0點,3點,6點,9點。分別用數字表示為:0,1,2,3.

9個操作分別操控著一些鐘錶,被操作的鐘錶每次順時針旋轉90°

求出最小操作集

1 abde

2 abc

3 bcef

4 adg

5 bdefh

6 cfi

7 degh

8 ghi

9 efhi

每個表有4狀態,一共9個表。我們可以用9維陣列儲存所有可能的狀態。

用結構體陣列的方式方便了回溯時對這幾個操作的辨認。

這種演算法優點:運用陣列偏移量進行遍歷,速度較快;不用動態生成結點,減少空間與時間的消耗。(普通節點演算法,vijos平台每組資料1000ms左右,而這種九維陣列的方法每組資料平均200ms左右)

稍微有點欠缺的地方是演算法一半的空間用來記錄回溯的路徑。。。

#include"stdio.h"

#include"queue"

#include"stack"

#include"memory.h"

using namespace std;

struct node

;node set[4][4][4][4][4][4][4][4][4];//1~9個表,每個表都有4鐘狀態,所以用9維陣列表示全部狀態 ,link作為回溯時的線索。

int tag[10] = ;//1~9各個維度的容量

int move1[9][9] = ;

int cinf();

node* move(node *p, int i);

int main()

else if (q->data == -1) //遍歷到目標跳出迴圈

}if (q->data == -1) //遍歷到目標跳出迴圈

}stack < int > stk; //定義乙個棧,因為回溯是逆序,棧來儲存方便輸出

while (q->link) //反向回溯

q = q->link;

} while (!stk.empty()) //列印棧內元素

printf("\n");

//fclose(stdin);

return 0;

}node* move(node *p, int i) //基位址p,操作i,返回對應操作後的位址,通過指標偏移量的方式比較高效

else

if ((p - begin) / tag[j] == 1)

if ((p - begin) / tag[j] == 2)

p += tag[j];

}end = begin + tag[j] - 1;

} else

if ((p - begin) / tag[j] == 2)

if ((p - begin) / tag[j] == 3)

end = begin + tag[j] - 1;

} }return p;

}int cinf()

Vijos P1016北京2008的掛鐘

題意 開9維的bfs,看了別人的優化方法是 用到了優先佇列,因為求的最短的操作路徑,所以用當前的步數作為優先佇列的條件,步數少的優先 include include include include include using namespace std int flag 4 4 4 4 4 4 4 ...

vijosP1016 北京2008的掛鐘

vijosp1016 北京2008的掛鐘 思路 dfs。對操作搜尋更加優秀,所以採用搜尋每乙個操作的使用次數,因為運算元為4則相當於沒有操作,所以列舉上限為3。1 include2 include3 include4 using namespace std 56 int op 9 9 7 8 9 1...

1016 計算利息

時間限制 1 秒 記憶體限制 32 兆 特殊判題 否 提交 39 解決 29 為自行解決學費,小明勤工儉學收入10000元以1年定期存入銀行,假設年利率為3.7 利率按年計算,表示100元存1年的利息為3.7元。實際上有時提前有時推遲取,因此實際利息按天計算,1年按365天計算,因此q天的利息是本金...