Codeforces Round 954 (Div. 3)部分题解A~D+F

A. X Axis

题目大意

给x轴上三点,要求找出一点到三点的距离和最小。

思路

三点中间点即是满足条件最优点。

代码实现
void solve(){
    vector<ll>o(3);
    for (int i = 0; i < 3; i++)cin >> o[i];
    sort(o.begin(), o.end());
    cout << abs(o[1] - o[0]) + abs(o[1] - o[2]) << "\n";
}

B. Matrix Stabilization

题目大意

给定一矩阵,要求让矩阵上每个点都不满足严格大于周围的点,每次只能让一个值减一,求最终矩阵什么样要求最少操作。

思路

判即可。

让不满足的变成周围四个点中最大得的即可。

代码实现
ll dt[210][210];
void solve(){
    ll n, m; cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> dt[i][j];
        }
    }
    ll fx[4][2] = { {0,1},{1,0},{-1,0},{0,-1} };
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            ll sum = 0;
            ll be = 4;
            for (int ii = 0; ii < 4; ii++) {
                ll xx = fx[ii][0] + i;
                ll yy = fx[ii][1] + j;
                if (xx<1 || xx>n || yy<1 || yy> m) {
                    be--;
                    continue;
                }
                if (dt[xx][yy] < dt[i][j])sum++;
            }
            if (be == sum) {
                ll mx = -1e12;
                for (int ii = 0; ii < 4; ii++) {
                    ll xx = fx[ii][0] + i;
                    ll yy = fx[ii][1] + j;
                    if (xx<1 || xx>n || yy<1 || yy> m) {
                        continue;
                    }
                    mx = max(dt[xx][yy], mx);
                }
                dt[i][j] = mx;
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cout << dt[i][j] << " \n"[j == m];
        }
    }
}

C. Update Queries

题目大意

给定一个长度为n的字符串,然后给你一个可以任意排序的操作序列,再给一组可以任意排序的字符序列,要求进行完操作的字符串字典序最小。

思路

我们对操作和字符序列进行从小到大排序,对于同一位置的操作,我们可以让他一开始对应较大字典序的字符,然后最后一次用字典序最小的字符。

代码实现
void solve() {
    ll n, m; cin >> n >> m;
    string s; cin >> s;
    vector<ll>o(m);
    for (int i = 0; i < m; i++) {
        cin >> o[i];
    }
    sort(o.begin(), o.end());
    string b; cin >> b;
    sort(b.begin(), b.end());
    deque<char>p;
    for (auto c : b)p.push_back(c);
    queue<char>todo;
    for (int i = 0; i < m - 1; i++) {
        if (o[i + 1] == o[i]) {
            todo.push(p.back());
            p.pop_back();
        }
        else {
            todo.push(p.front());
            p.pop_front();
        }
    }
    todo.push(p.front()); p.pop_front();
    for (int i = 0; i < m; i++) {
        char c = todo.front(); todo.pop();
        s[o[i] - 1] = c;
    }
    cout << s << "\n";
}

D. Mathematical Problem

题目大意

给定一个数字字串,要求加入n-2个加或乘在序列里面,求最小值。

思路

对应n=2的字串,直接输出即可。

对于字符串中存在0的,我们只需要判断0两侧可以都可以加乘号,即可直接输出最小值。

1两边如果可以加的话,让他加乘号最优,初次之外都加加号最优。

对于其他情况,我们让每两个成一组,硬判即可。

代码实现
ll o[210000];
ll num(ll l, ll r) {
    ll sum = 0;
    for (int i = l; i <= r; i++) {
        sum += o[i];
        if (i != r)sum *= 10;
    }
    return sum;
}
void solve() {
    ll n; cin >> n;
    bool flag = false;
    for (int i = 1; i <= n; i++) {
        char c; cin >> c;
        o[i] = c - '0';
        if (o[i] == 0 && ((n == 2 || (n == 3 && i == 2))==false))flag = true;
    }
    if (flag) {
        cout << "0\n"; return;
    }
    if (n == 2) {
        cout << num(1, 2) << "\n"; return;
    }
    ll ans = 1e18;
    for (int i = 1; i < n; i++) {
        ll sum = 0;
        bool flag = 0;
        for (int j = 1; j <= n; j++) {
            ll now = o[j];
            if (j == i) {
                j++; now *= 10; now += o[j];
            }
            if (now == 1) {
                flag = true;
            }
            else {
                sum += now;
            }
        }
        if (sum == 0 && flag) {
            sum = 1;
        }
        ans = min(ans, sum);
    }
    cout << ans << "\n";
}

F. Non-academic Problem

题目大意

给定一个无向图,要求减去图中一个边,使可以互相到达的顶点数量最小。

思路

tarjan求割边板子题。

无向图中,减去一个桥,才可以让答案变化。

我们只需要在判断减下每个桥之后答案的最小值即可。

代码实现
ll n, m;
ll low[MAXN], dfn[MAXN], dfs_clock;
bool isbridge[MAXN];
vector<ll> G[MAXN];
ll cnt_bridge;
ll father[MAXN], siz[MAXN];
ll ans = LLONG_MAX;
void tarjan(int u, int fa) {
    father[u] = fa;
    low[u] = dfn[u] = ++dfs_clock;
    siz[u] = 1;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!dfn[v]) {
            tarjan(v, u);
            low[u] = min(low[u], low[v]);
            siz[u] += siz[v];
            if (low[v] > dfn[u]) {
                isbridge[v] = true;
                ans = min(ans, siz[v] * (siz[v] - 1) / 2 + (n - siz[v]) * (n - siz[v] - 1) / 2);
                ++cnt_bridge;
            }
        }
        else if (dfn[v] < dfn[u] && v != fa) {
            low[u] = min(low[u], dfn[v]);
        }
    }
}
void solve() {
    cin >> n >> m;
    dfs_clock = 0; cnt_bridge = 0;
    ans = LLONG_MAX;
    for (int i = 1; i <= n; i++) {
        father[i] = 0; low[i] = 0; dfn[i] = 0;
        G[i].clear(); isbridge[i] = false;
        siz[i] = 0;
    }
    for (int i = 1; i <= m; i++) {
        ll x, y; cin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    tarjan(1, 0);
    if (ans == LLONG_MAX) {
        cout << n * (n - 1) / 2 << "\n";
        return;
    }
    cout << ans << "\n";
}

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值