Atcoder ABC285 赛后总结

A—Edge Checker 2

传送门

题目大意

给你一棵,输入两个 \(1 - 15\) 的数 \(a, b\),求 \(a\) 是否是 \(b\) 老爹父亲

这颗树如图 :

Image

题目解法

超级无敌暴力法(wu

一种最最最简单粗暴的方法就是把所有的关系存起来,然后每次输入都在这些里面搜一遍,有的话输出 Yes,没有的话输出 No

由于过于粗暴,作者就不写了(wu

正常的解法

看到这棵树可以发现一个普通树的规律:

左孩子编号等于该节点编号乘二,

右孩子编号等于该节点编号乘二加一。

又因为如果有关系的话肯定是 \(a\)\(b\) 的父亲,不可能是 \(b\)\(a\) 的父亲 整时空穿越了

所以答案就浮出水面了,我们只需要判断如下两个式子如果成立一个就是 Yes,都不成立就是 No

\[b = a \times 2 \]

\[b = a \times 2 + 1 \]

标程

#include <bits/stdc++.h>
using namespace std;
int a, b;
int main() {
    cin >> a >> b;
    if (b == a * 2) {
        cout << "Yes" << endl;
    } else if (b == a * 2 + 1) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    return 0;
}

B—Longest Uncommon Prefix

传送门

题目大意

给你一个长为 \(N\) 的字符串 \(S\) ,让你求出对于每一个 \(i\),求出最大的\(j(i + j \le N)\),满足:

\[\forall k \le j, S_k = S_{k + i} \]

题目解法

暴力

看到题目第一眼想到的是枚举每一个i,j,与k,暴力求出答案。

代码:

看正解去!

正解

看样例解释就能发现,我们就能发现

其实我们只需要枚举 \(i\)\(k\) 就可以了,因为实际上k的最大值就是j的最大值

具体的,拿样例来说:

当 \(i=1\)\(S_1​ \ne S_2​\) , \(S_2​ \ne S_3\) ​, … , \(S_5​ \ne S_6\) ​, 所以最大值为 \(j=5\)

当 \(i=2\)\(S_1​ \ne S_3\) , \(S_2​ = S_4\) 所以最大值为 \(j=1\)

当 \(i=3\)\(S_1​ \ne S_4\) , \(S_2​ \ne S_5\) , \(S_3 =S_6\) 所以最大值为 \(j=2\)

当 \(i=4\) , \(S_1​ = S_5\) 所以最大值为 \(j=0\)

当 \(i=5\)\(S_1​ \ne S_6\) 所以最大值为 \(j=1\)

标程

#include <bits/stdc++.h>
using namespace std;
int n;
string s;
int main() {
    cin >> n;
    cin >> s;
    s = ' ' + s;
    for (int i = 1; i < n; i++) {
        int ans = 0;
        for (int j = 1; j + i <= n; j++) {
            if (s[j] != s[j + i]) {
                ans = j;
            } else {
                break;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

C—Brutmhyhiizp

传送门

题目大意

Atcoder 中有肥肠多的题目,他们都按以下规则编号:

A, B, ... , AA, AB, ..., BA, ... , AAA, ...

现在要求你求出所给编号的题目是第几题

解法

暴力

一个一个数,这样代码很难写,而且还拿不到满分,肥肠的笨蛋,我也不写代码了(wu

正解

相信对于数学战斗力爆表的你们来说,肯定能一下就想到这道题跟进制有关系.

实际上这就是一个27进制的体现:

空=0,A=1,B=2,......,Z=26

所以实际上这道题就是一道进制转换题,瞬间没难度了

该不会还有人不会进制转换吧

标程

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
string s;
LL ans; // 不开longlong见祖宗!
int main() {
    cin >> s;
    ans = 0;
    for (int i = 0; i < s.size(); i++) {
        ans *= 26;
        ans += s[i] - 'A' + 1;
    }
    cout << ans << endl;
    return 0;
}

D—Change Usernames

题目大意

\(N\)homo网友,他们都想换个网名,可是不能有任何一个瞬间有俩人网名一样,而且呢,服务器只能同时改变个网友的网名

他就问你,如果你是服务器你能安排改变网名的顺序并符合以上条件吗,是则输出 Yes,否则输出 No

解法

首先,我们一看到这个题:一个玩意儿变另外一个玩意儿,这不是图吗。的确,这道题使用图解,但是,不是在网友之间连线,是在网名之间连线。

???

实际上我们要做的就是是整个离散化,然后把网名整成数字,然后扔进图里。

我们就直接忽略网友在网名之间连线

是不是茅塞顿开了。

那扔进图里了,要干啥?

我们先看看第二个样例:

Input

3
a b
b c
c a

Output

No

我们把图画出来后发现是这样子的:

graph LR A((a)) --> B((b)) B --> C((c)) C --> A

我们发现它成环了

这样,在环中,无论先改哪个,都会与已有网名重叠

所以实际上这道题就是判这张图有没有环,有的话输出 No,没有的话输出 Yes。(不要搞反了

那判环要用什么算法呢?

DFS!

想出来了吗?答案就在上面,框一下就出来了。

标程

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+5;
int n;
string s[N];
string t[N];
int cnt;
string hsh_hdl[2 * N];
map<string, int> hdl_hsh;
vector<int> G[2 * N];
int color[2 * N];
bool dfs(int u) {
    color[u] = 0;
    for (int v: G[u]) {
        if (color[v] == 0) {
            return false;
        } else if (color[v] == -1) {
            if (!dfs(v)) {
                return false;
            }
        }
    }
    color[u] = 1;
    return true;
}
int main() {
    memset(color, -1, sizeof color);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> s[i] >> t[i];
        if (!hdl_hsh[s[i]]) {
            cnt++;
            hdl_hsh[s[i]] = cnt;
            hsh_hdl[cnt] = s[i];
        }
        if (!hdl_hsh[t[i]]) {
            cnt++;
            hdl_hsh[t[i]] = cnt;
            hsh_hdl[cnt] = t[i];
        }
        G[hdl_hsh[s[i]]].push_back(hdl_hsh[t[i]]);
    }
    bool ans = true;
    for (int i = 1; i <= cnt; i++) {
        if (color[i] == -1) {
            if (!dfs(i)) {
                ans = false;
                break;
            }
        }
    }
    if (ans) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    return 0;
}

至于后面4题,小编不会了,原谅一下。

posted @ 2023-01-16 14:13  LightningCreeper  阅读(42)  评论(0编辑  收藏  举报