AtCoder Beginner Contest 361 A->F题解

  A

  没啥好说的

int n, k, A[N], x;
void solve()
{
  cin >> n >> k >> x;
  for (int i = 1; i <= n; i++)
    cin >> A[i];
  for (int i = 1; i <= k; i++)
  {
    cout << A[i] << " ";
  }
  cout << x << " ";
  for (int i = k + 1; i <= n; i++)
  {
    cout << A[i] << " ";
  }
}

B

 没开出来,阴间

int a, b, c, d, e, f;
int g, h, i, j, k, l;
bool check(int a, int b, int c, int d)
{
  return max(a, c) < min(b, d);
}
void solve()
{
  cin >> a >> b >> c >> d >> e >> f >> g >> h >> i >> j >> k >> l;
  if (check(a, d, g, j) && check(b, e, h, k) && check(c, f, i, l))
  {
    cout << "Yes";
  }
  else
    cout << "No";
}

C

 排序+双指针

LL n, k, A[N];
void solve()
{
  cin >> n >> k;
  for (int i = 1; i <= n; i++)
    cin >> A[i];
  sort(A + 1, A + n + 1);
  LL ans = 1e18;
  for (int i = 1, j = n - k; i <= k+1; i++,j++)
  {
    // cout << A[i] << "  " << A[j] << endl;
    ans = min(ans, A[j] - A[i]);
  }
  cout << ans;
}

 D

 和八数码一样,bfs+map剪枝

int n;
string s, t;
struct w
{
  string a;
  int b;
};
void solve()
{
  cin >> n;
  cin >> s >> t;
  map<string, int> D;
  D[s] = 1;
  string a = "--";
  s = s + a;
  queue<w> DD;
  DD.push({s, 0});
  while (!DD.empty())
  {
    w f = DD.front();
    DD.pop();
    string qq = f.a.substr(0, n);
    // cout << f.a << endl;
    if (qq == t)
    {
      cout << f.b;
      return;
    }
    int st = 0;
    for (int i = 0; i < n + 1; i++)
    {
      if (f.a[i] == '-')
      {
        st = i;
        break;
      }
    }
    for (int i = 0; i < n + 1; i++)
    {
      if (f.a[i] == '-' || f.a[i + 1] == '-')
        continue;
      string g = f.a;
      g[i] = '-', g[i + 1] = '-';
      // cout << g << endl;
      g[st] = f.a[i], g[st + 1] = f.a[i + 1];
      if (D[g])
        continue;
      // cout << f.a << "     " << g << "   " << i << "   " << st << endl;
      D[g] = 1;
      DD.push({g, f.b + 1});
    }
  }
  cout << "-1";
}

 E

  容易想到就是所有路都走俩边,可以选择一条为主路就走一遍,就是2*路长-树的直径

#define int long long
int n, u, v, ans = -1, w, ru[N];
vector<pair<int, int>> A[N];
int dfs(int x, int fa)
{
  int d1 = 0, d2 = 0;
  for (auto y : A[x])
  {
    if (y.first == fa)
      continue;
    int d = dfs(y.first, x) + y.second;
    if (d >= d1)
    {
      d2 = d1, d1 = d;
    }
    else if (d > d2)
    {
      d2 = d;
    }
  }
  ans = max(ans, d1 + d2);
  return d1;
}
void solve()
{
  cin >> n;
  LL num = 0;
  for (int i = 1; i < n; i++)
  {
    cin >> u >> v >> w;
    A[u].push_back({v, w});
    A[v].push_back({u, w});
    num += 2 * w;
    ru[u]++;
    ru[v]++;
  }
  if (n == 2)
  {
    cout << num / 2 << endl;
    return;
  }
  int st = 1;
  while (ru[st] == 1)
    st++;
  int k = dfs(st, -1);
  cout << num - ans;
}

 F

  就是暴力枚举, 三次和以上的, 二次的特殊一下

LL n, k, cnt = 0, x = 0;
map<LL, int> D;
void s(LL n)
{
  for (LL i = 2; i * i * i <= n; i++)
  {
    LL t = i * i * i;
    while (t <= n)
    {
      t *= i;
      if (D[t])
        continue;
      if ((LL)sqrtl(t) * (LL)sqrtl(t) == t)
        x++;
      D[t] = 1, cnt++;
    }
  }
}
void solve()
{
  cin >> n;
  s(n);
  cout << (LL)sqrtl(n) + cnt - x;
}

AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值