比赛链接: http://codeforces.com/contest/604
题目大意:
根据给定的CF的计分规则,给出5道题下来CF的最终得分。
解题思路:
模拟一下就好。
参考程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
|
#include <map> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define lson l, mid, ls #define rson mid, r, rs #define ls (rt << 1) + 1 #define rs (rt << 1) + 2 using namespace std; const int MAXN = 10000;
int m[6]; int w[6]; int x[] = {500, 1000, 1500, 2000, 2500};
int main(){ int hs, hu; while(scanf("%d", &m[0]) != EOF){ for(int i = 1; i < 5; i++) scanf("%d", &m[i]); for(int i = 0; i < 5; i++) scanf("%d", &w[i]); scanf("%d%d", &hs, &hu);
int ans = 0;
for(int i = 0; i < 5; i++) ans += max(3 * x[i] / 10, (x[i] - m[i] * x[i] / 250) - 50 * w[i]);
ans += (100 * hs - 50 * hu);
printf("%d\n", ans); } return 0; }
|
题目大意:
把 n 个物品放入箱子里, 一共有 k 个箱子供选择, 可以不全用上, 每个箱子可以放一个或者两个物品, 每件物品都有一个体积 $s_i$, 对于任意的体积 $s_i$ 的物品都可以放入到空间大于或者等于 $s_i$ 的箱子里面去(即不考虑物品的形状), 求一种组合方案, 可以用最多 k 个箱子装下 n 个物品的前提下, 所使用的最大的那个箱子的体积尽可能小, 求出那个体积。
其中:
$1 <= n <= 2k ≤ 100000$
$1 <= s_1 <= s_2 <= … <= s_n <= 1000000$
解题思路:
二分答案, 只要验证二分出来的答案是否满足题意就行了, 找出最小的那个答案。
参考程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#include <map> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define lson l, mid, ls #define rson mid, r, rs #define ls (rt << 1) + 1 #define rs (rt << 1) + 2 using namespace std; const int MAXN = 100100;
int n, k; int a[MAXN];
bool check(int x){ int num = k; int l = 0; for(int i = n - 1; i >= l; i--){ if(a[i] > x) return false; if(a[i] + a[l] <= x) l++; num--; } if(num < 0) return false; return true; }
int main(){ while(scanf("%d%d", &n, &k) != EOF){ for(int i = 0; i < n; i++) scanf("%d", &a[i]);
int l = a[0] - 1, r = a[n - 1] * 2, mid; while(r - l > 1){ mid = (l + r) >> 1; if(check(mid)) r = mid; else l = mid; } printf("%d\n", r); } return 0; }
|
题目大意:
给定一个01串, 长度为 n, 任意选定一个区间(或者不选)将区间内的01反转,使得这个01串中的01子序列最长。比如 10000011 可以反转中间的两个变成 10011011, 此时它拥有最长的01子序列 10011011,答案为 5.
其中 $1 <= n <= 100000$
解题思路:
选定一个区间翻转后,区间中的01子序列的长度是一定的,整个01串中的01子序列的长度改变是由反转区间的两端的改变造成的,所以只需要记录两端的改变即可,具体看代码。
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#include <map> #include <cmath> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <string> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define lson l, mid, ls #define rson mid, r, rs #define ls (rt << 1) + 1 #define rs (rt << 1) + 2 using namespace std; const int MAXN = 100100;
char ch[MAXN];
int main(){ int n; while(scanf("%d", &n) != EOF){ scanf(" %s", ch); int a = 0, b = 0; for(int i = 1; i <= n; i++){ if(ch[i] == ch[i - 1]) b++; else a++; } int ans = a + (b > 2 ? 2 : b); printf("%d\n", ans); } return 0; }
|