hihoCoder1233(2015北京网络赛H题)
生活随笔
收集整理的這篇文章主要介紹了
hihoCoder1233(2015北京网络赛H题)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載自:http://blog.csdn.net/queuelovestack/article/details/48625899
?
題意:
有n個卡槽,放有體積不同的n個空盒子,每次你可以移動一個空盒子到相鄰卡槽,但前提是相鄰卡槽若已經有空盒子,那么要移動的空盒子體積必須小于已有的空盒子,問要移動多少步才能使得從左到右,每個卡槽空盒子的體積遞增。
現用①表示1號卡槽,②表示2號卡槽,依次類推……
?
思路:
狀態壓縮,狀態表示每個盤子所在的位置,每個盤子的位置用三位二進制表示,總共的狀態為2^21,因為每次盤子只能向左放或者向右放,那么我們從結束的位置開始搜索,bfs預處理出目標狀態到所有狀態所需要的最小步數,然后對于每個詢問O(1)回答即可。
?
代碼:
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<ctime> #define eps 1e-6 #define LL long long #define pii pair<int, int> //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std;const int MAXN = 5000000; int n; int a[10], b[10]; int vis[MAXN]; bool fuck[10]; void bfs(int n) { queue<int> q;int tmp = 0;for(int i = 0; i < n; i++) {tmp += (i+1) * (1 << (3*i));}q.push(tmp);vis[tmp] = 0;while(!q.empty()) {int s = q.front(); q.pop();memset(fuck, 0, sizeof(fuck));for(int i = 0; i < n; i++) { //i+1在哪個位置 int pos = (s >> (3*i)) % 8;if(fuck[pos]) continue;fuck[pos] = 1;if(pos>1 && !fuck[pos-1]) {int t = s - (1<<(3*i));if(vis[t]==-1) {q.push(t);vis[t] = vis[s] + 1;} }if(pos<n && !fuck[pos+1]) {int t = s + (1<<(3*i));if(vis[t]==-1) {q.push(t);vis[t] = vis[s] + 1;}}}} } int main() {//freopen("input.txt", "r", stdin);int T; cin >> T;memset(vis, -1, sizeof(vis));for(int i = 1; i <= 7; i++) bfs(i);while(T--) {scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%d", &a[i]), b[i] = a[i];sort(b+1, b+n+1);for(int i = 1; i <= n; i++) a[i] = lower_bound(b+1, b+n+1, a[i]) - b - 1;int s = 0;for(int i = 1; i <= n; i++) {s += i*(1<<(3*a[i]));}printf("%d\n", vis[s]);}return 0; }?
?
?
?
?
總結
以上是生活随笔為你收集整理的hihoCoder1233(2015北京网络赛H题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hihoCoder1228(2015北京
- 下一篇: poj2079(一堆点找出最大的三角形)