序列相關的趣題 之四,序列相關趣題
(8) 給定一個英文單詞,消除其中重複的字母,只能刪掉字母,不能交換字母順序,最後原單詞中每個字母只出現一次,求字典序最小的結果。
這是toj一個題,百度面試也問過,原題見 http://acm.tju.edu.cn/toj/showp3257.html
此題我非常喜歡,巧妙之處是其演算法是O(n)的…… 。我們一個字母一個字母加入序列,一旦來了一個比較“小”的字母,因為我們需要字典順序最小,我們希望它儘可能靠前。所以我們試圖“冒泡”似的把小的往前面送,經過尾部那些較大的字母暫時扔掉,如果它們在後面還會出現的話,後面會加入進來。但是如果我們經過的字母后面再也不出現了,冒泡也就停止了,這個較小的字母也只能暫時停在這裡了。這符合我們的直覺,“最後一次出現”的大字母是有用的,因為我們最終不能少字母。題目比較簡單,但需要細細思考。
上My Code:
#include <cstdio>#include <cstring>#include <stack>#include <string>#include <vector>using namespace std;char s[1024],answer[30];int main() {int z;for (scanf("%d",&z);z;--z) {scanf("%s",s);stack<int> st;vector<int> num(26,0);for (int i = 0; s[i]; ++i) {++num[s[i] - 'a'];}vector<bool> have(26,false);for (int i = 0; s[i]; ++i) {int c = s[i] - 'a';--num[c];if (!have[c]) {for (;(!st.empty()) && num[st.top()] && (st.top() > c); have[st.top()] = false,st.pop());st.push(c);have[c] = true;}}answer[st.size()] = 0;for (int i = st.size(); !st.empty(); answer[--i] = st.top() + 'a',st.pop());puts(answer); }return 0;}
代碼裡記錄了一個字母后面還要出現多少次,還有它是否已經在堆棧中了。因為每個字母最多進出堆棧一次,所以複雜度是O(n)的。
(9) 一個特殊的“堆棧”,只有push_back,push_front和pop_back三種操作,運算元的順序就是1-n, 給出最後彈出數的順序,問之前操作的順序如何或者根本不可能。
這個題是網上看到的rocket fuel的面試。因為是面試題,沒地方提交…… 代碼也是自己想的,歡迎提意見。首先假設彈出的數在數組a裡面,並且數組a是1-n的一個排列,即數組a不缺少數,不重複數,沒有非法的超出範圍的數。
因為所有的數是按1-n的順序添加進去的,如果一個數x先被彈出來,小於x的數應該都在裡面了。它們在裡面的順序如何呢? 這個和“時間戳記”相關了,先彈出來的肯定在尾部,所以我們先統計每個數的“時間戳記”,然後在彈出x之前,根據小於x的時間戳記,決定那些數每個是push_front還是push_back。用雙端隊列類比,最後看一下隊尾是不是我要的那個數就可以了。我定義了一個結構op,裡面是pair<int,int>第一個表示運算元,第二個表示前進、後進、出。其實第一維可以省略的。
代碼:
bool solution(vector<int> &a,vector<pair<int,int> > &op) {int n = a.size();vector<int> ord(n + 1);for (int i = 0; i < n; ++i) {ord[a[i]] = i;}deque<int> q;/*1 push_back-1 push_front0 pop_back*/op.clear();for (int i = 1, j = 0;j < n; ++j) {for (;i <= a[j]; ++i) {if ((q.empty()) || (ord[q.back()] > ord[i])) {q.push_back(i);op.push_back(make_pair(i, 1));}else {q.push_front(i);op.push_back(make_pair(i, 0));}}if ((q.empty()) || (q.back() != a[j])) {op.clear();return false;}q.pop_back();op.push_back(make_pair(a[j], 0));}return true;}
四年級數學趣題及答案
1.小華的爸爸1分鐘可以剪好5隻自己的指甲。他在5分鐘內可以剪好幾隻自己的指甲?
2.小華帶50元錢去商店買一個價值38元的小汽車,但售貨員只找給他2元錢,這是為什嗎?
3.小軍說:“我昨天去釣魚,釣了一條無尾魚,兩條無頭的魚,三條半截的魚。你猜我一共釣了幾條魚?”同學們猜猜小軍一共釣了幾條魚?
4.6匹馬拉著一架大車跑了6裡,每匹馬跑了多少裡?6匹馬一共跑了多少裡?
5.一隻綁在樹榦上的小狗,貪吃地上的一根骨頭,但繩子不夠長,差了5厘米。你能教小狗用什麼辦法抓著骨頭呢?
6.王某從甲地去乙地,1分鐘後,李某從乙地去甲地。當王某和李某在途中相遇時,哪一位離甲地較遠一些?
7.時鐘剛敲了13下,你現在應該怎麼做?
8.在廣闊的草地上,有一頭牛在吃草。這頭牛一年才吃了草地上一半的草。問,它要把草地上的草全部吃光,需要幾年?
9.媽媽有7塊糖,想平均分給三個孩子,但又不願把餘下的糖切開,媽媽怎麼辦好呢?
10.公園的路旁有一排樹,每棵樹之間相隔3米,請問第一棵樹和第六棵樹之間相隔多少米?
11.把8按下面方法分成兩半,每半各是多少?算術法平均分是____,從中間橫著分是____,從中間豎著分是____。
12.一個房子4個角,一個角有一隻貓,每隻貓前面有3隻貓,請問房裡共有幾隻貓?
13.一個房子4個角,一個角有一隻貓,每隻貓前面有4隻貓,請問房裡共有幾隻貓?
14.小軍、小紅、小平3個人下棋,總共下了3盤。問他們各下了幾盤棋?(每盤棋是兩個人下的)
15.小明和小華每人有一包糖,但是不知道每包裡有幾塊。只知道小明給了小華8塊後,小華又給了小明14塊,這時兩人包裡的糖的塊數正好同樣多。同學們,你說原來誰的糖多?多幾塊?
答案:
1.20隻,包括手指甲和腳指甲
2.因為他付給售貨員40元,所以只找給他2元;
3.0條,因為他釣的魚是不存在的;
4.6裡,36裡;
5.只要教小狗轉過身子用後腳抓骨頭,就行了。
6.他們相遇時,是在同一地方,所以兩人離甲地同樣遠;
7.應該修理時鐘;
8.它永遠不會把草吃光,因為草會不斷生長;
9.媽媽先吃一塊,再分給每個孩子兩塊;
10.15米;
11.4,0,3。
12.4隻;
13.5隻;
14.2盤;
15.原來小華糖多;14-8=6塊,因為多給了6塊兩人糖的塊數正好同樣多,所以原來小華比小明多12塊。
已知一個資料序列ak(題30表),通過第四類部分響應形成系統,如題30圖所示試填出表中所列其它資料
預編碼:A(K)模2加法(K-2)等於b(K)
B(K)雙極性轉換,然後進行相關的編碼
相關編碼: B(K)-b選項(k-2的)是等於c(千)