2024初秋集訓——提高組 #35

Yaosicheng124發表於2024-10-10

A. 語言

題目描述

在一個語言中,有 \(26\) 種單詞,每個單詞用一個小寫英文字母表示。每種單詞可能有多種詞性,詞性有名詞(\(N\))、動詞(\(V\))、形容詞(\(A\))。我們定義一個名詞短句(\(NP\))為一個名詞(\(N\))或一個形容詞加名詞短句(\(A+NP\))或兩個名詞短句(\(NP_1+NP_2\)),一個句子(\(S\))為一個名詞短句加動詞加名詞短句(\(NP_1+V+NP_2\))。

現在給定一些單詞,請你判斷它有沒有可能是一個句子。

思路

很明顯一段子串是名詞短句當且僅當其中只包含 \(N,P\) 且最後一個單詞為 \(N\)。所以我們列舉動詞在哪裡,並預處理前字尾是否為名詞短句即可。

時空複雜度均為 \(O(N)\)

程式碼

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 100001;

int t, n, a[26];
bool ok[MAXN];
string s;

void Solve() {
  for(int i = 0; i < 26; ++i) {
    cin >> a[i];
  }
  cin >> s;
  n = s.size(), s = ' ' + s;
  ok[n] = (a[s[n] - 'a'] == 2 || a[s[n] - 'a'] == 3 || a[s[n] - 'a'] == 6 || a[s[n] - 'a'] == 7);
  for(int i = n - 1; i >= 1; --i) {
    ok[i] = (ok[i + 1] & (a[s[i] - 'a'] == 1 || a[s[i] - 'a'] == 2 || a[s[i] - 'a'] == 3 || a[s[i] - 'a'] == 5 || a[s[i] - 'a'] == 6 || a[s[i] - 'a'] == 7));
  }
  bool op = (a[s[1] - 'a'] == 1 || a[s[1] - 'a'] == 2 || a[s[1] - 'a'] == 3 || a[s[1] - 'a'] == 5 || a[s[1] - 'a'] == 6 || a[s[1] - 'a'] == 7);
  for(int i = 2; i < n; ++i) {
    if((a[s[i] - 'a'] == 4 || a[s[i] - 'a'] == 5 || a[s[i] - 'a'] == 6 || a[s[i] - 'a'] == 7) && op && (a[s[i - 1] - 'a'] == 2 || a[s[i - 1] - 'a'] == 3 || a[s[i - 1] - 'a'] == 6 || a[s[i - 1] - 'a'] == 7) && ok[i + 1]) {
      cout << "Yes\n";
      return;
    }
    op &= (ok[i + 1] & (a[s[i] - 'a'] == 1 || a[s[i] - 'a'] == 2 || a[s[i] - 'a'] == 3 || a[s[i] - 'a'] == 5 || a[s[i] - 'a'] == 6 || a[s[i] - 'a'] == 7));
  }
  cout << "No\n";
}

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  for(cin >> t; t--; Solve()) {
  }
  return 0;
}

B. 色球

題目描述

\(N\) 個棧,和 \(N\) 種顏色的球。給定 \(M\) 次操作。

  • 往第 \(z\) 個棧壓入 \(x\) 個顏色為 \(y\) 的球。
  • 彈出第 \(z\) 個棧的頂部 \(x\) 個球,並求出最後一個球的顏色。
  • 將第 \(u\) 個棧的球依次彈出並壓入 \(v\) 中。

思路

這裡主要是第三個操作最難處理。第三個操作很明顯可以用啟發式合併解決,但是它在彈出和壓入時會進行反轉,所以我們可以對每個棧記錄其有沒有反轉過,如果反轉了則壓入和刪除都要從棧底進行,所以改用雙端佇列即可。

空間複雜度 \(O(N+M)\),時間複雜度 \(O((N+M)\log N)\)

程式碼

#include<bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;

const int MAXN = 200001;

int n, m;
bool vis[MAXN];
deque<pii> que[MAXN];

int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  for(int i = 1, x, y, z; i <= m; ++i) {
    string op;
    cin >> op >> x >> y;
    if(op == "push") {
      cin >> z;
      if(!vis[z]) {
        que[z].push_front({y, x});
      }else {
        que[z].push_back({y, x});
      }
    }else if(op == "pop") {
      int ans = 0;
      for(; x; ) {
        if(!vis[y]) {
          auto &[a, b] = que[y].front();
          ans = a;
          if(b <= x) {
            x -= b;
            que[y].pop_front();
          }else {
            b -= x;
            break;
          }
        }else {
          auto &[a, b] = que[y].back();
          ans = a;
          if(b <= x) {
            x -= b;
            que[y].pop_back();
          }else {
            b -= x;
            break;
          }
        }
      }
      cout << ans << "\n";
    }else if(op == "put") {
      if(que[x].size() < que[y].size()) {
        for(; !que[x].empty(); ) {
          if(!vis[x]) {
            auto [a, b] = que[x].front();
            if(!vis[y]) {
              que[y].push_front({a, b});
            }else {
              que[y].push_back({a, b});
            }
            que[x].pop_front();
          }else {
            auto [a, b] = que[x].back();
            if(!vis[y]) {
              que[y].push_front({a, b});
            }else {
              que[y].push_back({a, b});
            }
            que[x].pop_back();
          }
        }
      }else {
        swap(que[x], que[y]);
        swap(vis[x], vis[y]);
        for(; !que[x].empty(); ) {
          if(!vis[x]) {
            auto [a, b] = que[x].front();
            if(!vis[y]) {
              que[y].push_front({a, b});
            }else {
              que[y].push_back({a, b});
            }
            que[x].pop_front();
          }else {
            auto [a, b] = que[x].back();
            if(!vis[y]) {
              que[y].push_front({a, b});
            }else {
              que[y].push_back({a, b});
            }
            que[x].pop_back();
          }
        }
        vis[y] ^= 1;
      }
    }
  }
  return 0;
}

相關文章