AtCoder Beginner Contest 246

D - 2-variable Function

题意

给定一个整数 \(n\) \((1 \le n \le 10^{18})\), 找出一个最小整数 \(X\)
\(X\) 满足

  • \(X \ge n\)
  • 存在两个非负整数 \(a, b\) 满足 \(X = a^3 + a^2b + ab^2 + b^3\)

思路

\(X = a^3 + a^2 b + ab^2 + b^3 = (a^2+b^2) \times (a + b)\)
注意到 \(n\) 最大为 \(10^{18}\) , 那么 \(\sqrt[3]{n} \le 10^6\)
那么我们枚举 \(a\), 二分查找 \(b\) 即可

点击查看代码
/********************
Author:  Nanfeng1997
Contest: AtCoder - AtCoder Beginner Contest 246
URL:     https://atcoder.jp/contests/abc246/tasks/abc246_d
When:    2022-04-02 20:00:37

Memory:  1024MB
Time:    2000ms
********************/
#include  <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = unsigned long long;

void solve() {
  LL x; cin >> x;
  LL ans = 1e18;
  for(LL i = 0; i <= 1000000; i ++ ) {
    LL l = 0, r = 1000000;
    if(i * i * i > x) break;
    for(int t = 0; t < 100 && l != r; t ++ ) {
      LL mid = l + r >> 1;
      if((i + mid) * (i * i + mid * mid) < x) l = mid + 1;
      else r = mid;
    }
    // if(i == 1) cout << l << " " << r << "\n";
    if((i+l)*(i*i+l*l) >= x)
    ans = min(ans, (i+l)*(i*i+l*l));
  }
  cout << ans << "\n";

}

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

  return ~~(0 ^ _ ^ 0);
}

E - Bishop 2

题意

给定一个 \(n \times n\) 的地图,以及起点和终点,地图中有障碍物,地图中一个人从起点出发,每次可以沿着四个斜线方向走任意长度,但是不能途径障碍物,求从起点到终点的最短步数

思路

注意到这个人每次行走的时候是只能沿着直线走,每次拐弯步数就会 +1,因此我们可以进行 \(BFS\),由于我们进行比遍历的时候同方向行走转向行走两种行走方式对答案的影响是不同的,因此我们想到用 \(01-BFS\),维护一个双端队列 \(deque\),如果同方向就放在对头,否则放在队尾,保证这个队列有序即可做到每次更新是用最短距离更新的。

CODE

点击查看代码
/********************
Author:  Nanfeng1997
Contest: AtCoder - AtCoder Beginner Contest 246
URL:     https://atcoder.jp/contests/abc246/tasks/abc246_e
When:    2022-04-02 20:00:42

Memory:  2048MB
Time:    6000ms
********************/
#pragma GCC optimize(3)
#include  <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
using Ay3 = array<int, 3>;
void solve() {
  int n, sx, sy, ex, ey; 
  cin >> n >> sx >> sy >> ex >> ey;
  sx --, sy --, ex --, ey --;
  vector<string> s(n);
  for(auto &X: s) cin >> X;

  vector<int> dx{-1, -1, 1, 1}; vector<int> dy{-1, 1, -1, 1};  

  vector<vector<vector<int>>> d(n, vector<vector<int>>(n, vector<int>(4, 1e9)));
  vector<vector<vector<bool>>> vis(n, vector<vector<bool>>(n, vector<bool>(4, false)));

  deque<array<int, 3> > dq;

  auto ok = [&] (int X, int Y) {
    return X >= 0 && X < n && Y >= 0 && Y < n;
  };

  for(int i = 0; i < 4; i ++ ) {
    int x = sx + dx[i], y = sy + dy[i];
    if(!ok(x, y)) continue;
    if(s[x][y] == '#') continue;
    d[x][y][i] = 1;
    dq.push_back({x, y, i});
  }

  while(!dq.empty()) {
    Ay3 t = dq.front(); dq.pop_front();

    if(t[0] == ex && t[1] == ey) {
      cout << d[ex][ey][t[2]] << "\n";
      return ;
    }

    int x = t[0], y = t[1];

    if(vis[x][y][t[2]]) continue;
    vis[x][y][t[2]] = true;

    int dist = d[x][y][t[2]];

    for(int i = 0; i < 4; i ++ ) {
      int nx = x + dx[i], ny = y + dy[i];
      if(!ok(nx, ny) || s[nx][ny] == '#') continue;
      int nd = dist;
      if(i != t[2]) nd ++;
      if(d[nx][ny][i] > nd) {
        d[nx][ny][i] = nd;
        if(i == t[2]) {
          dq.push_front({nx, ny, i});
        } else {
          dq.push_back({nx, ny, i});
        }
      }
    }
  }
  cout << "-1\n";
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  solve();
  return ~~(0 ^ _ ^ 0);
}

另一种方法

点击查看代码
/********************
Author:  Nanfeng1997
Contest: AtCoder - AtCoder Beginner Contest 246
URL:     https://atcoder.jp/contests/abc246/tasks/abc246_e
When:    2022-04-02 20:00:42

Memory:  2048MB
Time:    6000ms
********************/
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include  <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;
using Ay2 = array<int, 2>;

void solve() {
  int n, sx, sy, ex, ey; 
  cin >> n >> sx >> sy >> ex >> ey;
  sx --, sy --, ex --, ey --;
  vector<string> s(n);
  for(auto &X: s) cin >> X;

  vector<int> dx{1, 1, -1, -1}; vector<int> dy{1, -1, -1, 1};  

  vector<vector<int>> d(n, vector<int> (n, -1));
  vector<vector<vector<bool>>> vis(n, vector<vector<bool>>(n, vector<bool>(2, false)));

  auto ok = [&] (int X, int Y) {
    return X >= 0 && X < n && Y >= 0 && Y < n;
  };

  queue<array<int, 2> > q;
  d[sx][sy] = 0;
  q.push({sx, sy});
  while(!q.empty()) {
    Ay2 t = q.front(); q.pop();
    for(int i = 0; i < 4; i ++ ) {
      int x = t[0], y = t[1];
      while(true) {
        x += dx[i], y += dy[i];
        if(!ok(x, y)) break;
        if(s[x][y] == '#') break;
        if(vis[x][y][i & 1]) break;
        vis[x][y][i & 1] = true;
        if(d[x][y] == -1) {
          d[x][y] = d[t[0]][t[1]] + 1;
          q.push({x, y});
        }
      }
    }
  }
  cout << d[ex][ey];
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  solve();
  return ~~(0 ^ _ ^ 0);
}

F - typewriter

题意

给定 \(n\) 个字符串,有一个打字机,打字机每次可以选择一个字符串进行打字,问打字机可以打出多少种不同的长度为 \(l\) 的字符串

思路

简单容斥 ,对于每个字符串,假设有 \(ch\) 种字符,那么他可以打出长度为 \(k\) 的字符串的种类数为 \({ch}^{k}\) , 考虑不同的字符串可以打出相同的字符,那么我们需要对答案进行容斥。
假设有 \(3\) 个字符串 \(s_1, s_2, s_3\) ,每个字符串的答案为 \({ans}_i\),那么最终的答案为

\(+ ans_1 + ans_2 + ans_3\)
\(- [(ans_1 \&\& ans_2) + (ans_1 \&\& ans_3) + (ans_2 \&\& ans_3)]\)
\(+ (ans_1 \&\& ans_2 \&\& ans_3)\)
简单来说,就是加上奇数个字符串都能构成的方案数,减去偶数个都能构成的方案数

点击查看代码
/********************
Author:  Nanfeng1997
Contest: AtCoder - AtCoder Beginner Contest 246
URL:     https://atcoder.jp/contests/abc246/tasks/abc246_f
When:    2022-04-02 20:00:46

Memory:  1024MB
Time:    2000ms
********************/
#include  <bits/stdc++.h>
#define _ 0
using namespace std;
using LL = long long;

const int MOD = 998244353;

int ksm(int a, int b, int p = MOD, LL ret = 1) {
  while(b) {
    if(b & 1) ret = ret * a % p;
    b >>= 1;
    a = 1LL * a * a % p;
  }
  return ret % p;
}
void solve() {
  int n, k; cin >> n >> k;
  vector<int> s(n, 0); 
  for(int i = 0; i < n; i ++ ) {
    string X; cin >> X;
    for(char &c: X) s[i] |= (1 << (c - 'a'));
  }
  LL ret = 0;
  for(int i = 1; i < 1 << n; i ++ ) {
    int ch = (1 << 26) - 1;
    for(int j = 0; j < n; j ++ ) if(i & (1 << j)) {
      ch &= s[j];
    }
    int pc = __builtin_popcount(ch);
    if(__builtin_parity(i)) {
      ret += ksm(pc, k); ret %= MOD;
    } else {
      ret += (MOD - ksm(pc, k)); ret %= MOD;
    }
  }
  cout << ret;

}

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

  return ~~(0 ^ _ ^ 0);
}

posted @ 2022-04-05 22:18  ccz9729  阅读(119)  评论(0编辑  收藏  举报