2015北京網賽 G Boxes bfs

2021-09-30 12:31:26 字數 1622 閱讀 7127

題目大意: 給你n( n < 8 ) 個互不相同的數, 問進行多少次操作後能讓這些數變成公升序, 無法變成就輸出-1, 具體操作是, 每個數只能每次只能移動到與他相鄰的空位或者比他大的數上。如:2, 1, 3 可以通過 2, , (1 3)—>   ,2,(1 3) —> , (1 2), 3 —> 1, 2, 3 這4次變換達到。

思路:就是狀態壓縮之後的bfs了, 用乙個n位整數來存每個數在第幾個位置上, 這裡不能存「第i個位置上是哪乙個數」這種狀態, 因為大多數狀態都是乙個位置上有多個數。然後從就可以從題目要求的最終狀態出發, 找到所有可達狀態了。也就是一開始1, 12, 123, 1234, ..., 1234567這些初始化為1,(初始化為1便於與不可達狀態區分, 正好輸出的時候dp[v] - 1 也同時可以讓不可達狀態的輸出是-1)。

狀態轉移的時候, 由於存的是每個數所在的位置, 所以要先處理一下, 用pos陣列存每個位置最上面的數, 這樣就可以判斷每個數能否左右移動, 也就是狀態轉移了。

一開始用string的map存, 跑了10s才出結果。。然後改整數存狀態就過了orz 可是整數存狀態在狀態轉移的時候要訪問某一位上的數又是一陣麻煩。。orz

/***************************************

zzblack **

2015-09-20 **

orz **

****************************************/

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;

#define ls id<<1,l,mid

#define rs id<<1|1,mid+1,r

#define off(x) memset(x,-1,sizeof x)

#define clr(x) memset(x,0,sizeof x)

#define mem(x) memset(x,0x3f,sizeof x)

typedef long long ll ;

typedef pairpii ;

const int maxn = 1e5+50 ;

const int inf = 0x3f3f3f3f ;

const int mod = 1e9+7 ;

mapmp;

int pos[10];

int get(int x)

return res;

}int get_n(int x)

return res;

}void init()

while (q.size())

for (int i = 1; i <= n; i++)

}if (i < n && pos[i] < pos[i + 1]) }}

}int main ()

return 0;

}

2018北京網路賽A題

一道搜尋題寫了好久沒寫出來 一直拖到現在才補起來 題目不難 只是有一些地方以前沒注意過 現把幾點要注意的指出來 一 因為每一次移動可能耗時1也可能耗時2 所以不能用單純的佇列 需要用優先順序佇列 二 因為氧氣罐數量的不同而導致狀態的不同 需要三維的陣列來記錄狀態 三 為了 的簡潔 把v陣列的判斷和賦...

acm 2018北京網路賽B題

這個題的題意就是給n n 10個字串,長度不超過8,但是n個字串每乙個都可以組成乙個環,然後求這n個字串的最長公共子串行 我的做法就是使用位運算遍歷。朱學長要打我.就是每一位就是乙個0 1,來遍歷,這樣就比for迴圈遍歷快很多,然後分別使用map來存同時要避免在每個字串中子串出現次數大於1,然後再用...

icpc 北京網路賽 1006 貪心演算法

網路賽結束,看了大神的 以後才寫出來的,這是一道貪心演算法,選區域性最優方案 就是相鄰兩個點不能直接到達做特別討論。易證 如果兩個點不能直接到達,那麼每次讓青蛙走兩步到達 l 1 的距離是最優選擇,如果現在青蛙的位置是now 那麼到達now 的那一步走了step,然後對now 後面的那個點進行討論 ...