Codeforces Intel Code Challenge Elimination Round(Oct/01/2016)

来源:互联网 发布:二阶矩阵 编辑:程序博客网 时间:2024/06/05 19:11

C
大意就是给定一个数列,每次使一个数变成0,求每次变化以后不包括零的子数列的和的最大值是多少。

可以逆推。
这让我想到了以前的一道题

http://blog.csdn.net/vectorxj/article/details/51477089 就是将问题反过来求并查集。

这道题其实道理也类似,问题就转化成每次加入一个数,求不包括零的子数列的和的最大值是多少。就需要用两个数组li,ri来存储当前已有的合法子数列的边界。另外,反过来以后答案肯定是不下降的,所以可以直接取max

#include <cstdio>#include <cstdlib>#include <iostream>#include <queue>using namespace std;typedef long long ll;inline char get(void) {    static char buf[100000], *p1 = buf, *p2 = buf;    if (p1 == p2) {        p2 = (p1 = buf) + fread(buf, 1, 100000, stdin);        if (p1 == p2) return EOF;    }    return *p1++;}template<typename T>inline int read(T &x) {    static char c; x = 0;    for (c = get(); c < '0' || c > '9'; c = get());    for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = get());    return x;}inline ll Max(ll a, ll b) {    return a > b ? a : b;}const int N = 100010, INF = 1 << 30;int q[N], l[N], r[N];ll num[N], ans[N];int n, x, y, p;int main(void) {    read(n);    for (int i = 1; i <= n; i++) {        read(num[i]); num[i] += num[i - 1];        l[i] = r[i] = i;    }    for (int i = 0; i < n; i++) read(q[i]);    for (int i = n - 1; i; i--) {        p = q[i]; x = l[p - 1];        if (l[p + 1] == p) y = r[p + 1];        else y = p;        ans[i] = Max(ans[i + 1], num[y] - num[x]);        l[y] = l[p] = x; r[x + 1] = y;    }    for (int i = 1; i <= n; i++) printf("%I64d\n", ans[i]);    return 0;}

D
两种变换:

1.Take any integer xi and multiply it by two, i.e. replace xi with 2·xi.
2.Take any integer xi, multiply it by two and add one, i.e. replace xi with 2·xi + 1.

问一个集合能否能由另一个集合变化而来,且该集合的元素最大值最小。
感觉很简单吧。贪心加搜索搞一搞就好了,每次找到最大值取出不断判断除以二之后的值是否属于集合即可。原理很好想。

#include <cstdio>#include <cstdlib>#include <iostream>#include <set>using namespace std;inline char get(void) {    static char buf[100000], *p1 = buf, *p2 = buf;    if (p1 == p2) {        p2 = (p1 = buf) + fread(buf, 1, 100000, stdin);        if (p1 == p2) return EOF;    }    return *p1++;}template<typename T>inline int read(T &x) {    static char c; x = 0;    for (c = get(); c < '0' || c > '9'; c = get());    for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = get());    return x;}const int N = 50010;struct cmp {    bool operator ()(int a, int b) {        return a > b;    }};typedef set<int, cmp> ms;ms S;int n, x, a[N];inline void Modify(int x) {    S.erase(S.find(x)); S.insert(x >> 1);}bool check(int x) {    if (!(x >> 1)) return false;    if (S.find(x >> 1) != S.end()) {        bool b = check(x >> 1);        if (b) Modify(x);        return b;    }    Modify(x);    return true;}int main(void) {    read(n);    for (int i = 1; i <= n; i++) S.insert(read(a[i]));    while (1) {        x = *S.begin();        if (!check(x)) break;    }    for (ms::iterator i = S.begin(); i != S.end(); i++)        printf("%d ", *i);}
0 0