Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

Posted kisekipurin2019

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)相关的知识,希望对你有一定的参考价值。

题目链接:https://codeforces.com/contest/1305

A - Kuroni and the Gifts

诚心诚意的签到题。

B - Kuroni and Simple Strings

题意:给一个括号串s。定义一个括号串是“简单括号串”,当且仅当其是"(((..("+")))...)"的形式,且前后两部分的长度相等。每次操作可以从括号串s中选择一个子序列,要求这个子序列是一个简单括号串,然后把整个子序列从s中删除。要求使用尽可能少的操作使得无法再操作。

题解:假如某个‘(‘的右边还有‘)‘,那么显然还可以继续操作。假如每次只能消除一对‘(‘和‘)‘,那么消除最左侧的‘(‘和最右侧的‘)‘是最好的,根据这个思路可以依次把最左和最右的括号匹配掉,当两边指针相遇之后就不会再有匹配的括号了。

char s[1005];
int ans[1005], atop;
 
void test_case() {
    scanf("%s", s + 1);
    int n = strlen(s + 1);
    int firstleft = -1, firstright = -1;
    for(int i = 1; i <= n; ++i) {
        if(s[i] == '(') {
            firstleft = i;
            break;
        }
    }
    if(firstleft == -1) {
        puts("0");
        return;
    }
    for(int i = firstleft + 1; i <= n; ++i) {
        if(s[i] == ')') {
            firstright = i;
            break;
        }
    }
    if(firstright == -1) {
        puts("0");
        return;
    }
    puts("1");
    int L = 1, R = n;
    atop = 0;
    while(L <= R) {
        if(s[L] == ')') {
            ++L;
            continue;
        }
        if(s[R] == '(') {
            --R;
            continue;
        }
        assert(L < R && s[L] == '(' && s[R] == ')');
        ans[++atop] = L;
        ans[++atop] = R;
        ++L;
        --R;
    }
    sort(ans + 1, ans + 1 + atop);
    printf("%d
", atop);
    for(int i = 1; i <= atop; ++i)
        printf("%d%c", ans[i], " 
"[i == atop]);
}

C - Kuroni and Impossible Calculation

题意:给一个n(<=2e5)个非负整数的序列,以及正整数m(<=1000),求 (prod_{1leq i < j leq n} |a_i-a_j| mod m) 的值。

题解:由于m比较小,所以有一些暴力的做法。假如n>=m+1,那么根据鸽巢原理答案就是0,否则n也会很小。n很小直接n^2计算即可。注意 (|a-b|mod m eq |a mod m - b mod m|) ,这个要分类讨论。

int n, m;
int a[200005];
 
void test_case() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    if(n >= m + 1) {
        puts("0");
        return;
    }
    sort(a + 1, a + 1 + n);
    ll res = 1;
    for(int i = 1; i <= n; ++i) {
        for(int j = 1; j < i; ++j) {
            res *= a[i] - a[j];
            if(res >= m)
                res %= m;
        }
    }
    printf("%lld
", res);
}

D - Kuroni and the Celebration

题意:给一棵n个节点的有根树,但是根未知,然后每次询问一对(u,v),评测机返回他们的LCA。使用不超过 (lfloor frac{n}{2} floor) 次询问确定根的编号。

题解:可以观察出,每次询问两个点(u,v),记得到的LCA为w。那么从w向u走和从w向v走的整棵子树都没用了。但是假如w是u和v其中之一,则只能去掉一棵子树,在极端情况下这棵子树只拥有一个节点,这样会导致询问超限。假如每次选的u和v都是叶子,那么w是u和v其中之一的情况,就可以立即确定其是根,否则一定可以去掉至少两个节点。也就是说一次询问至少去掉两个节点。易知最后的边界,会是一棵2个节点的树或者1个节点的树,假如把度数<=1的都叫做叶子,那么有可能会把1个节点的树的这个节点入队两次,把这个情况去掉,或者规定度数=1的才是叶子。

int n, rt;
set<int> G[1005];
int vis[1005];
 
queue<int> leaf;
 
int ask(int u, int v) {
    printf("? %d %d
", u, v);
    fflush(stdout);
    int w;
    scanf("%d", &w);
    if(w == u || w == v) {
        printf("! %d", w);
        fflush(stdout);
        exit(0);
    }
    return w;
}
 
void test_case() {
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n - 1; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        G[u].insert(v);
        G[v].insert(u);
    }
    for(int i = 1; i <= n; ++i) {
        if(G[i].size() <= 1) {
            leaf.push(i);
            vis[i] = 1;
        }
    }
    while(leaf.size() >= 2) {
        int u = leaf.front();
        leaf.pop();
        int v = leaf.front();
        leaf.pop();
        int w = ask(u, v);
        for(auto &eu : G[u]) {
            G[eu].erase(u);
            if(vis[eu] == 0 && G[eu].size() <= 1) {
                leaf.push(eu);
                vis[eu] = 1;
            }
        }
        for(auto &ev : G[v]) {
            G[ev].erase(v);
            if(vis[ev] == 0 && G[ev].size() <= 1) {
                leaf.push(ev);
                vis[ev] = 1;
            }
        }
    }
    assert(leaf.size() == 1);
    int r = leaf.front();
    printf("! %d", r);
    fflush(stdout);
    exit(0);
}

E - Kuroni and the Score Distribution

显然123456...x这样构造可以获得最大的平衡度,易知用完5000个数的平衡度都不会超过5000*5000。不少于m个平衡度是很好做的,但是比赛的时候不知道怎么弄到恰好m个平衡度,其实只需要调节最后一个x的大小,很明显x每增加1就会失去一个平衡度。这样总是有一个位置是刚刚好的,大概这最后一个数会在10000附近。假如还有剩下的数,就从1e6开始,每隔20000放一个就可以了。

F

有没有确定性的做法?

以上是关于Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)的主要内容,如果未能解决你的问题,请参考以下文章

Ozon Tech Challenge 2020 游戏存档

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

Ozon Tech Challenge 2020 C. Kuroni and Impossible Calculation 模数

[Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated]-E. Kuroni and the Score Distribution(构造)

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)

Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!)E(构造)