快轉到主要內容

Napoleon Cake

目錄

簡易題敘
#

題目給你 \(t\) 組測資,每組測資有 \(n\) 個數字(\(n\) 是蛋糕大小),一開始蛋糕是乾的,\(a_i\) 代表從 \(i\) 開始往下數 \(a_i\) 個(包含 \(i\) 自己)的蛋糕都有被淋濕,超過底部沒關係,求最後蛋糕各層有沒有濕,是濕的就輸出 \(1\),乾的輸出 \(0\)。

範例測資:

  • 輸入
3
6
0 3 0 0 1 3
10
0 0 0 1 0 5 0 0 0 2
3
0 0 0
  • 輸出
1 1 0 1 1 1 
0 1 1 1 1 1 0 0 1 1 
0 0 0 

概念講解
#

首先,因為一開始蛋糕是乾的,我們將差分陣列 \(dif\) 初始化為 \(0\)。

memset(dif, 0, sizeof(dif));

輸入 \(a_i\) 時,如果是 \(0\) 直接不理它,不是的話就在頭尾加 \(1\) 減 \(1\)(注意,超過第一層的要算到第一層,也就是三元運算子那塊)

for (int i = 1, x; i <= n; i++) {
    cin >> x;
    if (!x) continue;
    dif[(i - x + 1 > 0 ? i - x + 1 : 1)]++;
    dif[i + 1]--;
}

跑一遍每個位置的前綴和,大於 \(0\) 代表有淋濕,輸出 \(1\),否則是 \(0\)。

int now = 0;
for (int i = 1; i <= n; i++) {
    now += dif[i];
    cout << (now > 0 ? 1 : 0) << ' ';
}

範例程式碼
#

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int t, n, dif[N];
signed main() {
    cin >> t;
    while (t--) {
        cin >> n;
        memset(dif, 0, sizeof(dif));
        for (int i = 1, x; i <= n; i++) {
            cin >> x;
            if (!x) continue;
            dif[(i - x + 1 > 0 ? i - x + 1 : 1)]++;
            dif[i + 1]--;
        }
        int now = 0;
        for (int i = 1; i <= n; i++) {
            now += dif[i];
            cout << (now > 0 ? 1 : 0) << ' ';
        }
        cout << '\n';
    }
}
Piau 的筆記本
作者
Piau 的筆記本
希望我寫下來的東西能夠長久的記在我的腦中