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<=2105)条,第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<=210^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;
}