Codeforce:Good Bye 2020 个人题解

题面链接:Here

代码提交:Here

年终彩蛋

1466A. Bovine Dilemma

题意是:给定一个固定点(0,1),然后给定n个在x轴的点,求面积不同的三角形个数

简单思考一下就容易发现这个是一个高相等的三角形,只需要去比较底边的长度不同的有多少个即可。

//AC代码
void solve() {
    cin >> n;
    vector<int> v(n);
    for (int i = 0; i < n; ++i)
        cin >> v[i];
    if (n == 1) {
        cout << 0 << endl;
        return;
    }
    set<int> s;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            if (i != j)
                s.insert(v[j] - v[i]);
    //由于直接暴力找的答案是正解的两倍(会存入等大小的负值),所以要除2
    cout << s.size() / 2 << endl;
}

进阶挑战:Try to solve it for \(n,x_i≤10^5\).

//待补

1466B. Last minute enhancements

给定\(n\) 个音符的值,当可以为重复出现的值加一时,最终能有多少个不同音符

标记出现过的,如果下次还出现则令其加一再标记

//原提交写法
void solve() {
    cin >> n;
    vector<int> v(n);
    int cnt = 0, sum = 0;
    int book[2 * (n + 1)] = {0};
    set<int> s;
    for (int i = 0; i < n; ++i) {
        cin >> v[i];
        if (book[v[i]])
            v[i]++;
        s.insert(v[i]);
        book[v[i]]++;
    }
    if (n == 1) {
        cout << 1 << endl;
        return;
    }
    cout << s.size() << endl;
}
//写法优化
void solve() {
    ll n, x;
    cin >> n;
    set<ll> s;
    for (int i = 0; i < n; ++i) {
        cin >> x;
        if (s.count(x))
            x++;
        s.insert(x);
    }
    cout << s.size() << endl;
}
//多利用STL函数帮助解决问题

进阶挑战:对于给定的 \(k_i\),如果我们可以将音符 \(x_i\) 增加 [0,\(k_i\)]中的任何整数,可以解决吗?

//待补

1466C. Canine poetry

如果存在一个长度大于3的回文,则存在一个长度为2或3的回文。此观察结果使我们可以简化擦除所有长度为2或3的回文的任务。 每个字符最多将被替换一次。

从现在开始,有几种可能的解决方案。 最简单的方法是从左到右遍历一个单词。 当我们遇到以当前位置结束的回文(长度为2或3),并且由未标记的元素组成时,我们会贪婪地将此字符标记为要替换的字符。 标记字符的数目就是答案,因为事实证明,通过仅替换标记位置上的字母,我们可以获得有效的无回文序列。 复杂度为O(n)。

当然这道题也可以用DP做,但更复杂:时间复杂度\(O(n*26^2)\)

char s[N];
bool vis[N];
void solve() {
    cin >> (s + 1);
    n = strlen(s + 1);
    for (int i = 1; i <= n; i += 1)
        vis[i] = 0;
    int ans = 0;
    for (int i = 1; i <= n; i += 1) {
        if (i >= 2 and s[i] == s[i - 1] and not vis[i - 1]) {
            vis[i] = 1;
            ans += 1;
        }
        if (i >= 3 and s[i] == s[i - 2] and not vis[i - 2] and not vis[i]) {
            vis[i] = 1;
            ans += 1;
        }
    }
    cout << ans << "\n";
}

进阶挑战:如果字母可以更改,并且每次更改后都需要计算结果怎么办?

1466D. 13th Labour of Heracles

树构造,写一下入度和出度

ll w[N];
int d[N];
void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> w[i], d[i] = 0;

    for (int i = 1, u, v; i < n; i++) {
        cin >> u >> v;
        d[u] += 1, d[v] += 1;
    }

    ll ans = 0;
    vector<ll> v;
    for (int i = 1; i <= n; i++) {
        ans += w[i];
        for (int j = 1; j < d[i]; j++)
            v.push_back(w[i]);
    }
    sort(v.begin(), v.end(), greater<ll>());
    cout << ans << " ";
    for (ll x : v)
        cout << (ans += x) << " ";
    cout << endl;
}

1466E. Apollo versus Pan

//待补

1466F. Euclid's nightmare

//待补
posted @ 2020-12-31 13:02  RioTian  阅读(339)  评论(0编辑  收藏  举报