Codeforces Round #378 (Div. 2)
A. Grasshopper And the String
题意:
输入一个长度n不超过100的由英文大写字母组成的字符串,元音字母定义为'A','E','I','O','U','Y',起点为字符串的第一个字符的前一个位置,终点为字符串的最后一个字符的下一个位置,一只蟋蟀要从起点跳到终点,其中它每一步只能跳落到靠右最近邻的元音字符所在的位置,求从起点跳到终点的每一步中的最大步长为多少。
分析:
时间复杂度为O(n)。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100 + 3;
char arr[maxn];
int main() {
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
memset(arr, 0, sizeof(arr));
while (~scanf("%s", arr)) {
int ans = 0, pre = -1, len = strlen(arr);
for (int i = 0; i < len; i++) {
if (arr[i] == 'A' || arr[i] == 'E' || arr[i] == 'I' || \
arr[i] == 'O' || arr[i] == 'U' || arr[i] == 'Y') {
ans = max(ans, i - pre);
pre = i;
}
}
ans = max(ans, len - pre);
printf("%d\n", ans);
memset(arr, 0, sizeof(arr));
}
return 0;
}
B. Parade
题意:
在举办一个阅兵仪式,总共有n(1<=n<=10^5)列士兵,第i列有li(1<=li<=500)个士兵走步时是左脚起步的,有ri(1<=ri<=500)个士兵走步时是右脚起步的,这个阅兵仪式的美感程度可以如下衡量:如果L是n列士兵中左脚起步的士兵的数量,R是n列士兵中右脚起步的士兵的数量,那么美观程度就是|L-R|。你可以也仅可以让其中一列士兵中左脚起步的士兵改用右脚起步、右脚起步的士兵改用左脚起步。现要求应该让哪一列士兵做改变使得美观程度最大,输出列的编号,如果不做改变就已经达到最大的美观程度,就输出0。
分析:
计算不做任何改变时的美观程度,再枚举对每一列做改变是否有提高美观值。时间复杂度为O(n)。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cctype>
using namespace std;
const int maxn = 1e5 + 3;
int sum_ll[maxn], sum_rr[maxn], n;
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 main() {
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while (~scanf("%d", &n)) {
sum_ll[0] = sum_rr[0] = 0;
for (int i = 1; i <= n; i++) {
int ll, rr;
read(ll); read(rr);
sum_ll[i] = sum_ll[i - 1] + ll;
sum_rr[i] = sum_rr[i - 1] + rr;
}
int ans_idx = 0, ans = abs(sum_ll[n] - sum_rr[n]);
for (int i = 1; i <= n; i++) {
int ll = sum_ll[i] - sum_ll[i - 1];
int rr = sum_rr[i] - sum_rr[i - 1];
int rest_sum_ll = sum_ll[n] - ll;
int rest_sum_rr = sum_rr[n] - rr;
int buf = abs(rest_sum_ll + rr - rest_sum_rr - ll);
if (buf > ans) { ans = buf; ans_idx = i; }
}
printf("%d\n", ans_idx);
}
return 0;
}
D. Kostya the Sculptor
题意:
给出n(1<=n<=10^5)个长方体雕塑,每个长方体有长宽高为ai,bi和ci(1<=ai,bi,ci<=10^9)。现要送给一个朋友一个球形雕塑,你可以从n个长方体雕塑中选一个来雕塑,也可以从n个长方体中选两个(要求这两个长方体有一个面是完全吻合的,即长宽相等)长方体粘合在一起(完全相同的面粘在一起)来雕塑,为使得这个球形雕塑体积最大,问该如何选取长方体来雕塑。
分析:
贪心。为使球形雕塑体积最大,即使直径最大,直径即等于选取的一个长方体或黏合后的长方体的最短边的边长。先按只从中选取一个长方体,枚举选中每个长方体得到的直径,记录之中的最大直径,再将这些个长方体按照最长边、次长边、最短边的优先级来比较,排序这些长方体,因为选取两个长方体的目的是为了使得原来的最短边变大,因而若某两个长方体最长边和次长边相等(即可以黏合),则它们一定相邻,因此枚举每一对相邻的长方体,判断是否可以黏合,若可以黏合的话则记录最优直径,最后比较只选取一个长方体和选取两个长方体的最优直径即可。时间复杂度为O(nlogn)。
代码如下:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <cctype>
#include <algorithm>
using namespace std;
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();
}
}
const int maxn = 100000 + 3;
int n, one_val, one_idx, two_val, two_idx_1, two_idx_2;
struct Node {
int a, b, c, idx;
Node(int aa, int bb, int cc, int _idx): a(aa), b(bb), c(cc), idx(_idx) {}
bool operator < (const Node& rhs) const {
if (a != rhs.a) return a > rhs.a;
else if (b != rhs.b) return b > rhs.b;
else return c > rhs.c;
}
};
vector<Node> cube;
void solve() {
two_val = -1;
int bound = cube.size();
for (int i = 0; i < bound - 1; i++) {
if (cube[i].a == cube[i + 1].a && cube[i].b == cube[i + 1].b) {
int buf = min(min(cube[i].a, cube[i].b), cube[i].c + cube[i + 1].c);
if (buf > two_val) {
two_val = buf;
two_idx_1 = cube[i].idx;
two_idx_2 = cube[i + 1].idx;
}
}
}
if (two_val > one_val) printf("2\n%d %d\n", two_idx_1, two_idx_2);
else printf("1\n%d\n", one_idx);
}
int main() {
//freopen("input.txt", "r", stdin);
while (~scanf("%d", &n)) {
cube.clear();
one_val = -1;
for (int i = 1; i <= n; i++) {
int a, b, c;
read(a); read(b); read(c);
if (a < b) swap(a, b);
if (a < c) swap(a, c);
if (b < c) swap(b, c);
cube.push_back(Node(a, b, c, i));
if (c > one_val) { one_val = c; one_idx = i; }
}
sort(cube.begin(), cube.end());
if (n == 1) printf("1\n%d\n", one_idx);
else solve();
}
return 0;
}