牛客小白月赛 57

牛客小白月赛 57

链接

A. 最大面积

两个矩形的长宽分别取 \(min\) 即可.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
  int a, b, c, d; cin >> a >> b >> c >> d;
  cout << 1ll * min(a, c) * min(b, d);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int T = 1; //cin >> T;
  while(T -- ) solve();
  return 0;
}

B.种树

首先判断是否全为 \(1\) ,然后判断开头或者末尾是否为 \(1\) .

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
  int n; cin >> n;
  string s; cin >> s;
  int cnt = count(s.begin(), s.end(), '1');
  if (cnt == n) {
    cout << "0\n";
  } else {
    if (s[0] == '1' || s.back() == '1') {
      cout << "1\n";
    } else {
      cout << "2\n";
    }
  }
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int T = 1; //cin >> T;
  while(T -- ) solve();
  return 0;
}

C.奇怪的电梯

判断起点是否能到达 \(1\) 或者 \(n\),然后判断终点到 \(1\) 或者 \(n\) 的距离是否小于 \(k\),注意特判起点和终点重合.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

void solve() {
  ll n, k, a, b; cin >> n >> k >> a >> b;
  if (abs(a - b) > k || a == b) {
    cout << "YES\n";
  } else {
    if (abs(a - 1) > k || abs(a - n) > k) {
      if (abs(b - 1) > k || abs(b - n) > k) {
        cout << "YES\n";
        return ;
      }
    }
    cout << "NO\n";
  }

}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int T = 1; cin >> T;
  while(T -- ) solve();
  return 0;
}

D.最大 gcd

贪心,枚举答案,然后枚举倍数判断是否合法,复杂度为调和级数 \(O(n \log n)\).

点击查看代码
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

template <typename T> void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> void chkmin(T &x, T y) { x = min(x, y); }

void solve() {
  int n; cin >> n;
  vector<int> cnt(1000010);
  vector<int> a(n); for(int &x: a) cin >> x, cnt[x] ++;
  int mx = *max_element(a.begin(), a.end());
  int ans = 0;
  for (int i = 1; i <= mx; i ++ ) {
    int ct = 0;
    for (int j = i; j <= mx; j += i) {
      ct += cnt[j];
    }
    if (ct >= 2) {
      chkmax(ans, i);
    }
  }
  cout << ans << "\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int T = 1; //cin >> T;
  while(T -- ) solve();
  return 0;
}

E.一道难题

观察数据范围可以发现本题可以使用数位 DP 来解决,套用模板即可,不会 数位DP 的可以看 数位DP - Pecco的文章.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

template <typename T> void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> void chkmin(T &x, T y) { x = min(x, y); }

char s[100];
int n, cnt, a[100];
ll dp[25][4][2][2];

ll dfs(int pos, int len, bool flag, bool lead) {
  if (pos == n) {
    return len == 3;
  } 
  ll &ret = dp[pos][len][flag][lead];
  if (~ret) return ret; ret = 0;
  for (int i = 0; i <= (flag ? min(a[pos], 1) : 1); i ++ ) {
    ret += dfs(pos + 1, (i == 1) ? min(3, len + 1) : (len >= 3 ? 3 : 0), flag && (i == a[pos]), lead && !i);
  } 
  return ret;
}

void solve() {
  scanf("%s", s);
  n = strlen(s);
  for (int i = 0; i < n; i ++ ) a[i] = (s[i] - '0');
  memset(dp, -1, sizeof dp);
  cout << dfs(0, 0, true, true);
}

int main() {
  int T = 1; // cin >> T;
  while(T -- ) solve();
  return 0;
}

F.序列操作

首先观察可以发现 \(x\) 的取值为 \([0, p - 1]\) ,因此可以通过枚举答案求解,但是复杂度为 \(O(n \times p)\) 无法通过本题.

我们的目的是让 \(a_i + k \times x \equiv b_i (\mod p)\),因此 \(k \times x \equiv (b_i - a_i) (\mod p)\),由于 \(p\) 是质数,因此对于一个确定的 \(x\) 可以使用费马小定理来求解次数 \(k\) ; 观察到对于相同的 \(b_i - a_i\) 我们其实只需要一次计算即可,对于本质不同的 \(b_i - a_i (\mod p)\) 只有 \(p\) 个,因此 \(O(p ^ 2)\) 枚举答案即可.

点击查看代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;

template <typename T> void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> void chkmin(T &x, T y) { x = min(x, y); }

ll ksm(ll a, ll b, ll p, ll ret = 1) {
  while (b) {
    if (b & 1) ret = ret * a % p;
    b >>= 1;
    a = a * a % p;
  }
  return ret;
}

constexpr int N = 1E6 + 10;
int n, p, a[N], b[N];

void solve() {
  cin >> n >> p;
  for (int i = 1; i <= n; i ++ ) {
    cin >> a[i]; a[i] %= p;
  }
  for (int i = 1; i <= n; i ++ ) {
    cin >> b[i];
  }
  vector<int> c(p); bool flag = true;
  for (int i = 1; i <= n; i ++ ) {
    int x = (b[i] - a[i]) % p;
    if (x < 0) x += p;
    if (x) c[x] ++, flag = false;
  }
  if (flag) return cout << "0", void();
  n = c.size();
  int ans, inf = INT_MAX;
  for (int x = 1; x < p; x ++ ) {
    int q = ksm(x, p - 2, p);
    int res = 0;
    for (int i = 1; i < p; i ++ ) if (c[i]) {
      chkmax(res, (q * i) % p);
    }
    if (res < inf) {
      inf = res;
      ans = x;
    }
  }
  cout << ans;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int T = 1; // cin >> T;
  while(T -- ) solve();
  return 0;
}
posted @ 2022-09-18 22:40  ccz9729  阅读(36)  评论(0编辑  收藏  举报