Codeforces Round #379 (Div. 2)

Codeforces Round #379 (Div. 2)#

A. Anton and Danik##

题意:
输入一个长度为n(n<=100000)的字符串,'A'表示Anton,'D'表示Danik,每个字符表示每一局比赛的胜者,输出赢的次数比较多的那一方的名字,若输赢一样多,则输出Friendship。

分析:
时间复杂度为O(n)。

代码如下:

#include <cstdio>
#include <cstring>

const int maxn = 1e5 + 3;
char arr[maxn];
int n;

int main() {
  //freopen("input.txt", "r", stdin);
  while (~scanf("%d", &n)) {
    memset(arr, 0, sizeof(arr));
    scanf("%s", arr);
    int a_cnt = 0, d_cnt = 0, len = strlen(arr);
    for (int i = 0; i < len; i++) {
      if (arr[i] == 'A') a_cnt++;
      else if (arr[i] == 'D') d_cnt++;
    }
    if (a_cnt == d_cnt) puts("Friendship");
    else a_cnt > d_cnt ? puts("Anton") : puts("Danik");
  }
  return 0;
}

B. Anton and Digits##

题意:
已知有k2个为‘2’数字位,k3个为‘3’的数字位,k5个为‘5’的数字位,k6个为‘6’的数字位,Anton最喜欢的数是32和256,他打算用已有的数字位凑出若干个32和若干个256,使凑出来的数的和尽量大,每个数字位只可以用一次,可以有冗余的数字位置。

分析:
贪心。为使和尽量大,就使256尽量多,所以优先凑256,凑完所有能凑的256再凑32。时间复杂度为O(1)。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int k2, k3, k5, k6;

int main() {
  //freopen("input.txt", "r", stdin);
  while (~scanf("%d", &k2)) {
    scanf("%d%d%d", &k3, &k5, &k6);
    int tfs = min(k2, min(k5, k6));
    int ans = 256 * tfs;
    k2 -= tfs; k5 -= tfs; k6 -= tfs;
    int tt = min(k3, k2);
    ans += tt * 32;
    printf("%d\n", ans);
  }
  return 0;
}

C. Anton and Making Potions##

题意:
Anton需要准备n(1<=n<=210^9)瓶药水,他还有一个特殊的壶,使得它准备一瓶药水只需x秒,同时,他还知道有以下两种咒语可以减少他准备药水的时间:
1.这种咒语可以减少准备一瓶药水的时间,这种咒语有m(1<=m<=2
105)条,第i条需要消耗bi(1<=bi<=2*109)点法力,它将准备一瓶药水需要x秒减少为只需ai(1<=ai<x)秒。
2.这种咒语可以迅速产生药水。这种咒语有k(1<=k<=2105)条,第i条消耗di(1<=di<=2*109)点法力,然后迅速产生ci(1<=ci<=n)瓶药水。
对于以上两种咒语,每种Anton都只可以选不超过一条咒语来使用,且Anton拥有的法力值只有s(1<=s<=2
10^9)点,而且这两种咒语一使用都是立即生效的,所以Anton现在想知道他准备n瓶药水最少需要的时间是多少。

分析:
dp+二分查找。dp[i]表示选用第i条第一种咒语所需的最少时间,状态转移方程为:dp[i]=min{dp[i], ai*(n-cj) 其中j=argmax cj s.t. dj <= s - bi}。寻找最优j采用二分查找。最终时间复杂度为O(mlogk)。

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <cctype>
#include <algorithm>
using namespace std;

const int maxn = 200000 + 3;
int n, m, k, x, s, a[maxn], b[maxn], c[maxn], d[maxn];

typedef long long ll;

inline void read(int& buf) {
  buf = 0;
  char c = getchar();
  while (!isdigit(c)) c = getchar();
  while (isdigit(c)) {
    buf = (buf << 3) + (buf << 1) + (c - '0'); c = getchar();
  }
}

int argmax_idx(int obj) {
  int left = 1, right = k;
  while (left < right) {
    int mid = (left + right + 1) >> 1;
    if (d[mid] <= obj) left = mid;
    else right = mid - 1;
  }
  return left;
}

int main() {
  //freopen("input.txt", "r", stdin);
  while (~scanf("%d", &n)) {
    read(m); read(k); read(x); read(s);
    for (int i = 1; i <= m; i++) read(a[i]);
    for (int i = 1; i <= m; i++) read(b[i]);
    for (int i = 1; i <= k; i++) read(c[i]);
    for (int i = 1; i <= k; i++) read(d[i]);
    ll ans = 0x3f3f3f3f3f3f3f3f;
    for (int i = 1; i <= m; i++) {
      int obj = s - b[i], change = x;
      if (obj >= 0) change = a[i];
      int idx = argmax_idx(obj), sub_num = 0;
      if (d[idx] <= obj) sub_num = c[idx];
      ll buf = ll(change) * ll(n - sub_num);
      ans = min(ans, buf);
    }
    int idx = argmax_idx(s);
    if (d[idx] <= s) ans = min(ans, ll(x) * ll(n - c[idx]));
    printf("%I64d\n", ans);
  }
  return 0;
}
posted @ 2016-12-07 22:08  Alexis Lacour  阅读(133)  评论(0编辑  收藏  举报