Contest 3/14

A:ARC112A

可以发现答案是一个等差数列,注意2L>R的时答案是0。

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;

    int m = 2000000;
    vector<long long> ans(m + 1);
    for (int i = 1; i <= m; ++i) {
        ans[i] = ans[i - 1] + i;
    }

    while (T --) {
        long long l, r;
        cin >> l >> r;
        if (l + l <= r) {
            cout << ans[r - l - l + 1] << '\n';
        } else {
            cout << 0 << '\n';
        }
    }

    return 0;
}
View Code

B:keyence2021B

可以发现尽量均匀地放是最优的,那么从小到大枚举mex,计算这个mex有多少个对于答案的贡献即可。

#include <bits/stdc++.h>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, k;
    cin >> n >> k;

    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }

    vector<int> cnt(n + 1);
    for (int i = 0; i < n; ++i) {
        cnt[a[i]] ++;
    }

    int cur = k;
    long long ans = 0;
    for (int i = 0; i <= n; ++i) {
        ans += 1LL * max(0, cur - cnt[i]) * i;
        cur = min(cur, cnt[i]);
    }

    cout << ans << '\n';

    return 0;
}
View Code

C:Codeforces1208C

观察到当N为4的倍数时,N^(N+3)=(N+1)^(N+2)=3,所以把网格分成四个四个的小格子,每个小格子填上N,N+1,N+2,N+3即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
  int N;
  cin >> N;
  vector<vector<int>> A(N, vector<int> (N));
  int X = 0;
  for (int i = 0; i < N; i += 2) {
    for (int j = 0; j < N; j += 2) {
      A[i][j] = X;
      A[i][j + 1] = X + 1;
      A[i + 1][j] = X + 2;
      A[i + 1][j + 1] = X + 3;
      X += 4;
    }
  }
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < N; ++j) {
      cout << A[i][j] << " \n"[j == N - 1];
    }
  }
  return 0;
}
View Code

D:GYM102920E

dp[i][0/1][0/1]表示到了第i个位置,之前的两局的胜负情况分别是0/1和0/1,转移枚举当前的两局的胜负情况即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  cin >> N;
  vector<int> P(N);
  for (int i = 0; i < N; ++i) {
    cin >> P[i];
  }
  vector<vector<vector<int>>> dp(N + 1, vector<vector<int>> (2, vector<int> (2)));
  dp[0][0][0] = 1;
  for (int i = 0; i < N - 1; ++i) {
    for (int a = 0; a < 2; ++a) {
      for (int b = 0; b < 2; ++b) {
        for (int c = 0; c < 2; ++c) {
          for (int d = 0; d < 2; ++d) {
            if (abs(a + c - b - d) == P[i]) {
              dp[i + 1][c][d] |= dp[i][a][b];
            }
          }
        }
      }
    } 
  }
  bool ok = false;
  for (int a = 0; a < 2; ++a) {
    for (int b = 0; b < 2; ++b) {
      if (dp[N - 1][a][b] && abs(a - b) == P[N - 1]) {
        ok = true;
      }
    }
  }
  if (ok) {
    cout << "YES" << '\n';
  } else {
    cout << "NO" << '\n';
  }
  return 0;
};
View Code

E:Codeforces1023E

一个比较自然的想法是每次询问下一步是否能连向终点,这样分别会从起点以及终点到达对角线,但是不一定相遇。在走的时候从起点出发时贪心地尽量向下走,从终点出发时尽量向左走,这样最终肯定会相遇。

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    auto query = [&] (int r1, int c1, int r2, int c2) -> bool {
        cout << '?' << ' ' << r1 + 1 << ' ' << c1 + 1 << ' ' << r2 + 1 << ' ' << c2 + 1 << endl;
        string ret;
        cin >> ret;
        if (ret == "YES") {
            return true;
        } else {
            return false;
        }
    };

    auto dis = [&] (int r1, int c1, int r2, int c2) -> int {
        return abs(r1 - r2) + abs(c1 - c2);
    };

    int x = 0;
    int y = 0;
    vector<pair<int, int> > path;
    path.emplace_back(0, 0);
    while (dis(0, 0, x, y) < n - 1) {
        if (query(x + 1, y, n - 1, n - 1)) {
            x ++;
        } else {
            y ++;
        }
        path.emplace_back(x, y);
    }

    int m = path.size(); 
    x = n - 1;
    y = n - 1;
    vector<pair<int, int> > b;
    b.emplace_back(n - 1, n - 1);
    for (int i = m - 2; i >= 0; --i) {
        if (query(0, 0, x, y - 1)) {
            y --;
        } else {
            x --;
        }
        b.emplace_back(x, y);
    }

    b.pop_back();
    while (!b.empty()) {
        path.push_back(b.back());
        b.pop_back();
    }

    cout << '!' << ' ';
    for (int i = 0; i + 1 < path.size(); ++i) {
        if (path[i].first != path[i + 1].first) {
            cout << 'D';
        } else {
            cout << 'R';
        }
    }

    cout << endl;

    return 0;
}
View Code

 

posted @ 2021-03-15 22:52  19992147  阅读(73)  评论(0编辑  收藏  举报