[mock]8月8日

來源:互聯網
上載者:User

標籤:blog   for   問題   div   代碼   line   amp   log   

第一題是整數的方陣,求其中的子方陣,和最大。返回最大和以及子方陣寬度。因為做了topcoder的題,所以比較順手,O(n^3)的複雜度。

pair<int,int> maxiSum(vector<vector<int> > &a) {  //first is n second is sum    int N = a.size();    int retVal = INT_MIN;    int n = 1;    // fix two columns, i, j    for (int i = 0; i < N; i++) {        vector<int> sum(N);        for (int j = i; j < N; j++) {            // calc the sum per line            for (int k = 0; k < N; k++) {                    sum[k] = sum[k] + a[k][j];            }            // calc the sum of the squere with i, j            int tmpSum = 0;            int w = j - i;            for (int m = 0; m < N; m++) {                if (m < w) {                    tmpSum += sum[m];                } else if (m == w) {                    tmpSum += sum[m];                    if (tmpSum > retVal) {                        retVal = tmpSum;                        n = w + 1;                    }                } else {                    tmpSum += sum[m];                    tmpSum -= sum[m - w - 1];                    if (tmpSum > retVal) {                        retVal = tmpSum;                        n = w + 1;                    }                }            }        }    }    return make_pair(n, retVal);}

第二題,是有個0和1的矩陣,求裡面每個位置到最近的0的距離(類似曼哈頓距離)。這個題一開始想動態規劃什麼的,都不合適,比較像洪泛,但如果從每個0或1出發,就效率很低,n^4和完全枚舉是一樣的。後來想到和之前topcoder的一道題挺像,可以先把0全部放到queue裡面,然後逐步往外擴,便可求得。

void make(vector<vector<int> > &matrix) {    int N = matrix.size();    vector<vector<int> > dist;    vector<vector<bool> > visited;    dist.resize(N);    visited.resize(N);    for (int i = 0; i < N; i++) {        dist[i].resize(N);        visited[i].resize(N);    }    queue<pair<int, int> > que;    for (int i = 0; i < N; i++) {        for (int j = 0; j < N; j++) {            if (matrix[i][j] == 0) {                dist[i][j] = 0;                visited[i][j] = true;                que.push(make_pair(i, j));            }        }    }    while (!que.empty()) {        pair<int, int> pp = que.front();        que.pop();                if (valid(pp.first - 1, pp.second, visited)) {            dist[pp.first - 1][pp.second] = dist[pp.first][pp.second] + 1;            que.push(make_pair(pp.first - 1, pp.second));            visited[][] = true;        }        if (valid(pp.first, pp.second - 1, visited)) {                }        if (valid(pp.first + 1, pp.second, visited)) {                }        if (valid(pp.first, pp.second + 1, visited)) {                }    }        // copy to matrix    matrix = dist;}bool valid(int i, int j, vector<vector<bool> > & visited) {    // return whether we need to process this elem    int N = visited.size();    if (i < 0 || j < 0 || i >= N || j >= N || visited[i][j]) {        return false;    }    return true;}

遍曆四個方向的代碼其實應該更精簡,類似如下:

dx[] = {-1,0,1,0}dy[] = {0,1,0,-1}x + dx[i]y + dy[i]

第三題當時沒有想出來,是求一個數組中子段和的絕對值最小值。比如如下數組,就是1+2+ -3的絕對值最小。

{1,2,-3,-100,3}

這個題目很自然會想到去用最大子段和的做法,但是(應該)不能類似動態規劃降到O(n)。關鍵是,不滿足最優子問題的特性。比如該數組中前三個元素的最優解是0,前兩個元素的最優解是2,0沒有用到之前最優解地方。

那麼正確的做法是可以記錄之前的首碼和,然後排序,就可以求得了。因為:|sum[i..j]| = |p[j] - p[i - 1]|,p是首碼和,那麼排完序後,相鄰的兩個就能求得絕對值最小,只是要注意,i從0開始,那麼p[-1]就是不包括0的情況,就是0,要在首碼和數組裡加一個0.

本題的首碼和數組排序完了就是如下,裡面兩個0,一個開始之前p[-1],一個p[2],就能求出sum[0..2]=0,絕對值最小。

{-97, -94,  0, 0, 1, 3}

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.