CodeForces Gym 102028 简要题解

Xu Xiake in Henan Province

模拟。

#include <bits/stdc++.h>

using namespace std;

int main() {
   
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  int tt;
  scanf("%d", &tt);
  while (tt--) {
   
    int total = 0;
    for (int i = 0; i < 4; ++i) {
   
      int x;
      scanf("%d", &x);
      if (x) {
   
        ++total;
      }
    }
    switch (total) {
   
      case 0:
        puts("Typically Otaku");
        break;
      case 1:
        puts("Eye-opener");
        break;
      case 2:
        puts("Young Traveller");
        break;
      case 3:
        puts("Excellent Traveller");
        break;
      case 4:
        puts("Contemporary Xu Xiake");
        break;
    }
  }
  return 0;
}

Ultraman vs. Aodzilla and Bodzilla

贪心,记 f ( x ) f(x) f(x) 表示造成 x x x 点伤害需要的时间,那么有两种方案:

  • 共打 f ( H P A + H P B ) f(HP_A + HP_B) f(HPA+HPB) 轮,在第 f ( H P A ) f(HP_A) f(HPA) 轮时打败 A A A
  • 共打 f ( H P A + H P B ) f(HP_A + HP_B) f(HPA+HPB) 轮,在第 f ( H P B ) f(HP_B) f(HPB) 轮时打败 B B B

输出方案贪心即可。

#include <bits/stdc++.h>

using namespace std;

int main() {
   
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  int tt;
  scanf("%d", &tt);
  while (tt--) {
   
    int hp_a, hp_b, attack_a, attack_b;
    scanf("%d %d %d %d", &hp_a, &hp_b, &attack_a, &attack_b);
    auto get_sum = [&](int x) {
   
      return (long long)x * (x + 1) >> 1;
    };
    auto get_round = [&](int x) {
   
      int result = 1;
      while (get_sum(result) < x) {
   
        ++result;
      }
      return result;
    };
    int round_a = get_round(hp_a), round_b = get_round(hp_b), round_total = get_round(hp_a + hp_b);
    long long answer = min((long long)attack_a * round_a + (long long)attack_b * round_total, (long long)attack_a * round_total + (long long)attack_b * round_b);
    string result(round_total, 'B');
    if ((long long)attack_a * round_a + (long long)attack_b * round_total == answer) {
   
      string current(round_total, 'A');
      for (int i = round_a; i < round_total; ++i) {
   
        current[i] = 'B';
      }
      if (get_sum(round_a) - hp_a > get_sum(round_total) - hp_a - hp_b) {
   
        current[get_sum(round_a) - hp_a - 1] = 'B';
      }
      result = min(result, current);
    }
    if ((long long)attack_a * round_total + (long long)attack_b * round_b == answer) {
   
      string current(round_total, 'B');
      for (int i = round_b; i < round_total; ++i) {
   
        current[i] = 'A';
      }
      long long remain_b = get_sum(round_b) - hp_b, remain_a = remain_b - (get_sum(round_total) - hp_a - hp_b);
      int last = -1;
      for (int i = 0; i < round_a; ++i) {
   
        if (remain_b >= i + 1) {
   
          last = i;
          current[i] = 'A';
          remain_b -= i + 1;
          remain_a -= i + 1;
        }
      }
      if (remain_a > 0) {
   
        current[last] = 'B';
        current[last + remain_a] = 'A';
      }
      result = min(result, current);
    }
    cout << answer << " " << result << endl;
  }
  return 0;
}

Supreme Command

考虑坐标时,显然两维独立。考虑一个点的位置,可以表示成 max ⁡ ( l , min ⁡ ( x , r ) ) + d \max(l, \min(x,r)) + d max(l,min(x,r))+d 的形式,可以快速维护。

再考虑第二问,不难发现棋盘可以用两条横线两条竖线划分成 9 9 9 部分,因为初始每行每列只有一个车,所以只有 4 4 4 个角的车会占领重复位置。在操作时移动分界线即可。

#include <bits/stdc++.h>

using namespace std;

int main() {
   
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(0);
  cin.tie(0);
  int tt;
  cin >> tt;
  while (tt--) {
   
    int n, m;
    cin >> n >> m;
    vector<int> x(n), y(n);
    vector<int> px(n), py(n);
    for (int i = 0; i < n; ++i) {
   
      cin >> x[i] >> y[i];
      --x[i];
      --y[i];
      px[x[i]] = i;
      py[y[i]] = i;
    }
    int lx = 0, rx = n - 1, dx = 0;
    int ly = 0, ry = n - 1, dy = 0;
    int llx = -1, rrx = n;
    int lly = -1, rry = n;
    int ul = 0, ur = 0, dl = 0, dr = 0;
    while (m--) {
   
      string type;
      cin >> type;
      if (type == "U") {
   
        int shift;
        cin >> shift;
        int low = max(lx + dx - shift, 0);
        int high = max(rx + dx - shift, 0);
        if (low == high) {
   
          lx = rx = 0;
        } else {
   
          lx = rx - high + low;
        }
        dx = high - rx;
      } else if (type == "D") {
   
        int shift;
        cin >> shift;
        int low = min(lx + dx + shift, n - 1);
        int high = min(rx + dx + shift, n - 1);
        if (low == high) {
   
          lx = rx = 0;
        } else {
   
          rx = lx + high - low;
        }
        dx = low - lx;
      } else if (type == "L") {
   
        int shift;
        cin >> shift;
        int low = max(ly + dy - shift, 0);
        int high = max(ry + dy - shift, 0);
        if (low == high) {
   
          ly = ry = 0;
        } else {
   
          ly = ry - high + low;
        }
        dy = high - ry;
      } else if (type == "R") {
   
        int shift;
        cin >> shift;
        int low = min(ly + dy + shift, n - 1);
        int high = min(ry + dy + shift, n - 1);
        if (low == high) {
   
          ly = ry = 0;
        } else {
   
          ry = ly + high - low;
        }
        dy = low - ly;
      } else if (type == "?") {
   
        int id;
        cin >> id;
        --id;
        printf("%d %d\n", max(lx, min(rx, x[id])) + dx + 1, max(ly, min(ry, y[id])) + dy + 1);
      } else if (type == "!") {
   
        auto get = [&](int x) {
   
          return (long long)x * (x - 1) >> 1;
        };
        long long answer = 0;
        if (lx == rx && ly == ry) {
   
          printf("%lld\n", get(n));
        } else if (lx == rx) {
   
          printf("%lld\n", get(ly + 1) + get(n - ry));
        } else if (ly == ry) {
   
          printf("%lld\n", get(lx + 1) + get(n - rx));
        } else {
   
          while (llx < lx) {
   
            ++llx;
            int id = px[llx];
            if (y[id] <= lly) {
   
              ++ul;
            }
            if (y[id] >= rry) {
   
              ++ur;
            }
          }
          while (rrx > rx) {
   
            --rrx;
            int id = px[rrx];
            if (y[id] <= lly) {
   
              ++dl;
            }
            if (y[id] >= rry) {
   
              ++dr;
            }
          }
          while (lly < ly) {
   
            ++lly;
            int id = py[lly];
            if (x[id] <= llx) {
   
              ++ul;
            }
            if (x[id] >= rrx) {
   
              ++dl;
            }
          }
          while (rry > ry) {
   
            --rry;
            int id = py[rry];
            if (x[id] <= llx) {
   
              ++ur;
            }
            if (x[id] >= rrx) {
   
              ++dr;
            }
          }
          printf("%lld\n", get(ul) + get(ur) + get(dl) + get(dr));
        }
      }
    }
  }
  return 0;
}

Keiichi Tsuchiya the Drift King

分是否取到最大值两种情况讨论一下。

#include <bits/stdc++.h>

using namespace std;

const double pi = acos(-1);

int main() {
   
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  int tt;
  scanf("%d", &tt);
  while (tt--) {
   
    int a, b, r, d;
    scanf("%d %d %d %d", &a, &b, &r, &d);
    double angle = d * pi / 180;
    if (angle >= atan((double)b / (a + r))) {
   
      printf("%.9lf\n", sqrt(b * b + (a + r) * (a + r)) - r);
    } else {
   
      printf("%.9lf\n", (r + a) * cos(angle) + b * sin(angle) - r);
    }
  }
  return 0;
}

Resistors in Parallel

考虑最后选择了 ∏ i = 1 k p i \prod_{i=1}^k p_i i=1kpi ,那么其贡献是 ∏ i = 1 k p i + 1 p i \prod_{i=1}^k \frac{p_i+1}{p_i} i=1kpipi+1 ,选前若干小的质数即可。

def gcd(x, y):
    if y:
        return gcd(y, x % y)
    return x

tt = int(raw_input<
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值