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天的利息是本金...