網易互娛9.27號19點研發崗筆試題解

一共四道編程. 前兩道比較簡單就不說了, 主要講講3,4道.

第三題: 開心消消樂
就是給你個M*N的二維矩陣, 每個塊有一個顏色, 如果它的四周有相同的顏色那麼就是連在一起的, 每次點擊一個色塊(要能點擊消除儘量多的, 如果有數量相同的點擊編號小的)進行消除, 然後消除後上面的掉下來, 如果某一列消失了, 右邊的補過來. 問最後這個矩陣還剩多少個方塊…

題解: 按照題意模擬即可, 每次dfs找出能消除最多的, 然後標記這些塊, 再寫個函數處理一下消除後的填充小果果, 一直處理下去就行. 考查代碼力.
AC Code

const int M = 55;
const int N = 25;
bool vis[M][N];
char s[M][N], ts[M][N];
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
int n, m;
void dfs(int x, int y, int &cnt, int flag) { // 找消除塊, 還能標記這些塊
    vis[x][y] = 1; ++ cnt;
    if (flag) ts[x][y] = '#';
    for (int i = 0 ; i < 4 ; ++ i) {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if (xx < 1 || xx > m || yy < 1 || yy > n) continue;
        if (s[xx][yy] != s[x][y] || vis[xx][yy] || s[xx][yy] == '#') continue;
        dfs(xx, yy, cnt, flag);
    }
}
void work() {  // 處理消除這些塊後矩陣的樣子
    for (int i = 1 ; i <= n ; ++ i) {
        int low = m, high = m-1;
        while(low >= 1 && high >= 1) {
            if (ts[low][i] != '#') -- low;
            else {
                high = low - 1;
                while(high >= 1 && ts[high][i] == '#') -- high;
                if (high >= 1) {
                    swap(ts[low][i], ts[high][i]);
                    -- low;
                }
            }
        }
    }
    int f = 0;
    for (int i = 1 ; i < n ; ++ i) {
        if (ts[m][i] == '#') {
            f = 1;
            for (int j = 1 ; j <= m ; ++ j) {
                ts[j][i] = ts[j][i+1];
            }
            ts[m][i+1] = '#';
        }
    }
    if (f) for (int j = 1 ; j <= m ; ++ j) ts[j][n] = '#';
    memcpy(s, ts, sizeof(s));
}

void solve() {
    scanf("%d%d", &m, &n);
    for (int i = 1 ; i <= m ; ++ i) {
        scanf("%s", s[i]+1);
    }
    int tot = 0;
    int ti = 0;
    while(1) {
        ++ ti;
        memset(vis, 0, sizeof(vis));
        int mx = 0, sx = -1, sy = -1;
        for (int i = 1 ; i <= m ; ++ i) {
            for (int j = 1 ; j <= n ; ++ j) {
                if (s[i][j] == '#' || vis[i][j]) continue;
                int cnt = 0;
                dfs(i, j, cnt, 0);
                if (cnt > mx) {
                    mx = cnt; sx = i, sy = j;
                }
                else if (cnt == mx && s[i][j] - '0' < s[sx][sy] - '0') {
                    sx = i, sy = j;
                }
            }
        }
        tot += mx <= 1 ? 0 : mx;
        if (mx <= 1) break;
        int cnt = 0;
        memset(vis, 0, sizeof(vis));
        memcpy(ts, s, sizeof(s));
        dfs(sx, sy, cnt, 1);
        work();
    }
    printf("%d\n", m*n - tot);
}

第四題: 數矩形
在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述
1
4
1 1
2 2
3 3
4 4
輸出5
題解: 這道題還是挺有意思的… 通過畫圖可以知道, 實際上就看能多分割出多少個矩形, 如果x2 < x1, 但是y2 > y1, 那就多分出了一個矩形了, 實際上有點像偏序, 也就是在確定好x的大小關係後, 尋找 當前比這個y小的有多少個, 有多少就加多少(注意處理x或者y相同的情況). 所以我們需要一個數據結構可以幫我們判斷出某個數是否在裏面, 比某個數小的數量是多少. 很明顯set(無法算數量)做不到, 我們要做的就是模擬這個功能的set, 我用的離散化 + 樹狀數組.

AC Code

const int maxn = 1e5+5;

struct BinaryIndexTree {  // 離散化 + 樹狀數組的模板
    int a[maxn], c[maxn], idx,  siz;
    bool d[maxn];

    BinaryIndexTree() {clear();}

    void push_back(int x){a[++idx]=x;}

    int size() {return siz;}

    void build() {
        sort(a+1, a+1+idx);
        idx = unique(a+1, a+1+idx) - a - 1;
    }

    bool exist(int x){ return d[get(x)]; }

    int get(int x) {
        return lower_bound(a+1, a+1+idx,x) - a;
    }

    void insert(int x) {
        int y = get(x);
        ++siz, d[y]=true;
        for(int i = y ; i <= idx ; i += i&-i)
            ++ c[i];
    }

    int sum(int p) {
        int res = 0;
        for(int i = p ; i ; i -= i&-i)
            res += c[i];
        return res;
    }

    //<=x的數的個數
    int lower(int x){ return sum(get(x)); }

    void clear() {
        for(int i = 0 ; i <= idx ; ++i)
            c[i] = d[i] = 0;
        idx = siz =0;
    }
}bit;

struct node {
    int x,y;
    bool operator<(const node &_) const {
        if (x != _.x) return x > _.x;
        return y > _.y;
    }
}a[maxn];

void solve() {
    int n;
    scanf("%d",&n);
    for (int i = 1 ; i <= n ; ++ i) {
        scanf("%d%d",&a[i].x,&a[i].y);
        bit.push_back(a[i].y);
    }
    sort(a+1,a+1+n);
    bit.build();
    ll ans=0;
    for(int i = 1 ; i <= n ; ++i) {
        if(a[i].x != a[i-1].x) // x相同, 不用計算小的值
            ans+=bit.lower(a[i].y);
        if(!bit.exist(a[i].y)) {
            ++ans; // 本身, 然後再把不在set的y插進去. 不重複加
            bit.insert(a[i].y);
        }
    }
    printf("%lld\n",ans);
    bit.clear();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章