首页 > 其他分享 >Educational Codeforces Round 157 (Rated for Div. 2)

Educational Codeforces Round 157 (Rated for Div. 2)

时间:2023-11-04 15:33:20浏览次数:35  
标签:Educational Rated 157 int pos cin ++ vector using

A. Treasure Chest

分类讨论一下,只有两种情况。

  1. 走到钥匙处,然后走到箱子处
  2. 走到箱子处,移动箱子,走到钥匙处,走回箱子处

对于第二种情况可以直接枚举箱子被移动到的位置

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;


void solve() {
    int x, y, k;
    cin >> x >> y >> k;
    int res = abs(y - 0) + abs(x - y);
    for (int i = x - k, cnt; i <= x + k; i++) {
        cnt = abs(x - 0) + abs(x - i) + 2 * abs(i - y);
        res = min(res, cnt);
    }
    cout << res << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

B. Points and Minimum Distance

这里面有个比较好想的结论是不要走回头路。

把所有的点排序一下,然后考虑把点分开,首先\(a_1\)一定是起点,要找到\(n-1\)个点到\(a_1\)的距离和最小,显然是\(a_2,a_3,\dots,a_n\),则取这些点做横坐标,剩下的点做纵坐标即可。

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;


void solve() {
    int n;
    cin >> n;
    vi a(n * 2 + 1);
    for (int i = 1; i <= n * 2; i++) cin >> a[i];
    sort( a.begin() + 1, a.end() );
    cout << a[n] - a[1] + a[n+n] - a[n+1] << "\n";
    for( int i = 1 , j = n + 1 ; i <= n ; i ++ , j ++ )
        cout << a[i] << " " << a[j] << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

C. Torn Lucky Ticket

这题,如果注意到长度不超过 5 的话,会比较好想。

首先把所有的字符串按照长度分类。

然后先枚举\(i+j\)长度,再枚举\(i\)的长度,这样可以算出\(j\)的长度。

假设\(|i+j|=4,|i|=1\),则就是用\(a,bcd\)拼成\(abcd\),根据题目可知\(a+b = c + d\),则有\(a=c + d - b\),\(O(n)\)的遍历长度为 1 和 3 的字符串,分别用桶统计\(a,c +d-b\)的值出现的次数,然后变量两个桶,把值相同的两个次数相乘再求和就是答案。

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;


void solve() {
    int n, res = 0;
    cin >> n;
    vector<vector<string>> cnt(6);
    string num;
    for (int i = 1; i <= n; i++)
        cin >> num, cnt[num.size()].push_back(num);

    for (int len = 2, mid; len <= 10; len += 2) {
        mid = len / 2;
        for (int l = 1, r; l <= 5; l++) {
            r = len - l;
            if (r < 1 or r > 5) continue;
            vector<int> a(50), b(50);
            for (auto s: cnt[l]) {
                int x = 0;
                for (int i = 0; i < min(mid, l); i++)
                    x += s[i] - '0';
                for (int i = mid; i < l; i++)
                    x -= s[i] - '0';
                if( x < 0 ) continue;
                a[x]++;
            }
            for (auto s: cnt[r]) {
                int x = 0;
                for (int i = max(r - mid, 0ll); i < r; i++)
                    x += s[i] - '0';
                for (int i = 0; i < r - mid; i++)
                    x -= s[i] - '0';
                if( x < 0 ) continue;
                b[x]++;
            }
            for (int i = 0; i < 50; i++)
                res += a[i] * b[i];
        }
    }
    cout << res << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    solve();
    return 0;
}

D. XOR Construction

以\(n=4\)为例子,对题目的定义做一些小修改方便理解

\[已知 a_i和 \begin{matrix} a_1=b_0\oplus b_1\\ a_2=b_1\oplus b_2\\ a_3=b_2\oplus b_3 \end{matrix} 令\begin{matrix} c_1=a_1\\ c_2= c_1\oplus a_2\\ c_3=c_2\oplus a_3 \end{matrix} 则 \begin{matrix} c_1=b_0\oplus b_1\\ c_2=b_0\oplus b_2\\ c_3=b_0\oplus b_3 \end{matrix} \]

首先我们知道 \(b_i\)是\([0,n)\),我们可以统计\(b_i\)二进制位每一位 1 出现的次数,对\(c_i\)做相同的统计,

如果一位上的数在\(c_i\)和\(b_i\)中出现的次数相同,则\(b_0\)这一位一定是\(0\),否则一定是\(1\),据此可退出\(b_0\)的值,然后就可以根据\(b_i=c_i\oplus b_0\)推出所有的\(b_i\)

#include <bits/stdc++.h>

using namespace std;

#define int long long

using vi = vector<int>;
using pii = pair<int, int>;

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n), b(n), cntA(31), cntB(31);
    for (int i = 1; i < n; i++)
        cin >> a[i] , a[i] ^= a[i-1];
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < 31; j++) {
            if ((i >> j) & 1) cntA[j]++;
            if ((a[i] >> j) & 1) cntB[j]++;
        }
    }
    for (int i = 0; i < 31; i++)
        b[0] += (cntA[i] != cntB[i]) * (1 << i);
    for (int i = 1; i < n; i++)
        b[i] = b[0] ^ a[i];
    for( auto i : b )
        cout << i << " ";
    cout << "\n";
    return 0;
}

E. Infinite Card Game

对于当前的卡牌,最优解一定是在能破防的情况下,防御力尽可能大。这样的话,对于每一张卡牌的后继实际上是唯一的。

此时可以转换成有向图,对于一个联通子图,如果有环,则子图所有的点都是平局,如果无环,还可以保证只有一个汇点,我们只需要知道汇点是谁的卡片,整张子图所有的卡片状态就可以确定了。

为了方便统计,把图建成反向图,根据起点种类染色,然后用拓扑序的形式完成对整张图的染色。

#include<bits/stdc++.h>

using namespace std;

using vi = vector<int>;
using pii = pair<int, int>;

#define mp make_pair

void solve() {
    int n;
    cin >> n;
    vector<pii> a(n);
    for (auto &i: a) cin >> i.first;
    for (auto &i: a) cin >> i.second;

    int m;
    cin >> m;
    vector<pii> b(m);
    for (auto &i: b) cin >> i.first;
    for (auto &i: b) cin >> i.second;

    sort(a.begin(), a.end());
    sort(b.begin(), b.end());

    vi aSufMaxPos(n), bSufMaxPos(m);
    aSufMaxPos[n - 1] = n - 1;
    for (int i = n - 2; i >= 0; i--) {
        aSufMaxPos[i] = aSufMaxPos[i + 1];
        if (a[i].second > a[aSufMaxPos[i]].second)
            aSufMaxPos[i] = i;
    }
    bSufMaxPos[m - 1] = m - 1;
    for (int i = m - 2; i >= 0; i--) {
        bSufMaxPos[i] = bSufMaxPos[i + 1];
        if (b[i].second > b[bSufMaxPos[i]].second)
            bSufMaxPos[i] = i;
    }

    vector<vi> g(n + m);
    vi inner(n + m);
    for (int i = 0, pos; i < n; i++) {
        pos = lower_bound(b.begin(), b.end(), mp(a[i].second + 1, 0)) - b.begin();
        if (pos == m) continue;
        pos = bSufMaxPos[pos] + n;
        // 正常应该是 i -> pos , 为了方便统计答案,反向建图
        g[pos].push_back(i), inner[i]++;
    }
    for (int i = 0, pos; i < m; i++) {
        pos = lower_bound(a.begin(), a.end(), mp(b[i].second + 1, 0)) - a.begin();
        if (pos == n) continue;
        pos = aSufMaxPos[pos];
        g[pos].push_back(n + i), inner[n + i]++;
    }

    queue<int> q;
    vi f(n + m);
    for (int i = 0; i < n; i++) {
        if (b.back().first > a[i].second) continue;
        // a[i] 做结尾时,所有的 b 都无法破防,则 a[i] 必胜
        f[i] = 1, q.push(i);
    }
    for (int i = 0; i < m; i++) {
        if (a.back().first > b[i].second) continue;
        // b[i] 做结尾时,所有 a 都无法破防,则 b[i] 必败
        f[n + i] = -1, q.push(n + i);
    }
    for (int u; !q.empty();) {
        u = q.front(), q.pop();
        for (auto v: g[u]) {
            f[v] = f[u];
            if (--inner[v] == 0) q.push(v);
        }
    }
    vi res(3);
    for (int i = 0; i < n; i++) {
        if (f[i] == 1) res[0]++;
        else if (f[i] == 0) res[1]++;
        else res[2]++;
    }
    cout << res[0] << " " << res[1] << " " << res[2] << "\n";
    return;
}

int32_t main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    for (cin >> TC; TC; TC--)
        solve();
    return 0;
}

标签:Educational,Rated,157,int,pos,cin,++,vector,using
From: https://www.cnblogs.com/PHarr/p/17809404.html

相关文章

  • Educational Codeforces Round 157 (Rated for Div. 2) D. XOR Construction
    题目链接题意给你\(n-1\)个整数\(a_1,a_2,\dots,a_{n-1}\)。你的任务是构造一个数组\(b_1,b_2,\dots,b_n\),使得:从\(0\)到\(n-1\)的每个整数都在\(b\)中出现一次;对于从\(1\)到\(n-1\)的每个\(i\),\(b_i\oplusb_{i+1}=a_i\)(其中\(\oplus\)表示......
  • How to format lists in pandoc-generated docx documents?
    Sorry,thelistindentationsarecurrentlyhard-codedandcan'tbecustomized.Youcould,however,postprocessthedocxproducedbypandoc,changingthefilenumbering.xmlinthedocxcontainer.Oryoucouldmodifythesourcecodeandrecompile.Thes......
  • Educational Codeforces Round 134 (Div.2) D 题解
    题目链接D.MaximumAND题目大意给定两组序列\(a\)\(b\),长度为\(n\),现有一新序列\(c\),长度也为\(n\)。其中,\(c_i=a_i\oplusb_i\)。定义\(f(a,b)=c_1\&c_2\&……\&c_n\)。现在你可以随意编排\(b\)序列的顺序,求\(f(a,b)\)的最大值。思路以下位运算均是......
  • Educational Codeforces Round 128 (Rated for Div. 2)
    添加链接描述C题显然二分0的数量,然后双指针,算一下前缀和后缀1的数量即可。#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<map>#include<vector>#include<set>#defineAputs("YES")#defineBputs("NO&q......
  • mysql数据库管理-FEDERATED存储引擎远程链接MYSQL
    开启FEDERATED存储引擎1.1、查看存储引擎存在的FEDERATED存储引擎就配置文件开启不存在就安装查看showengines;YES支持并开启DEFAULT支持并开启,并且为默认引擎;NO不支持;DISABLED支持,但未开启。创建federated引擎表创建语句最好和原表语句一样,当然去掉id的auto之类的。CREATE......
  • CF1572F Stations 题解-Segment Tree Beats
    20231025CF1572FStations题解-SegmentTreeBeats吉司机线段树好题!!!CF3400。传送门Statement有\(n\)个广播站,第\(i\)个广播站高度为\(h_i\),范围为\(w_i\)。初始\(h_i=0,w_i=i\)。广播站\(i\)能向广播站\(j\)传递消息,当且仅当\(i\lej\lew_i\),且\(h_i>\max\lim......
  • [转]Oracle数据文件损坏的模拟和修复(一) |ORA-01578 data block corrupted|
    造成数据块损坏的原因通常是由于开启了异步I/O或者增加了写进程,还有可能是硬件引起的,今天模拟一下该问题的发生及修复方法。由于水平有限,那面疏漏,欢迎大家指正。 创建测试环境建立测试表空间:123456create tablespacetestdatafile  '/u02/oradata/logdw......
  • Educational Codeforces Round 144(CF1796 D~E) 题解
    D.MaximumSubarray题目链接十分钟秒了一道*2000,非常爽,但是个人感觉确实非常简单。下面令\(b_i=a_{i}-x\),\(b_i'=a_i+x\)。因为\(k<=20\),因此考虑一个复杂度与\(k\)相关的做法。不妨dp:设\(f_{i,j,0/1}\)表示考虑了前\(i\)个数,对\(j\)个数加上了\(x\),第\(i\)......
  • Educational Codeforces Round 145 (Rated for Div. 2) B. Points on Plane
    给一个二维平面,你需要在上面放\(n\)个芯片。将一个芯片放在\((x,y)\)的代价为\(|x|+|y|\)。放\(n\)个代价的代价为,所有芯片中耗费的最大代价。并且你需要保证任意两个芯片之间的距离严格\(>1\)。现在给出\(n\)给芯片,询问放\(n\)个芯片的最小代价。一:不难想到......
  • Educational Codeforces Round 149 (Rated for Div. 2)
    这场D被切穿了。A题答案为x或者x-11B题答案就是最长的连续一段的长度+1证明的话大概可以将它看成是几段连续上升和下降的段,然后在峰谷、峰顶分别填上最小、最大,剩下的就依次递增或递减就行。C题将一段连续的0/1视作一个块,那么我们最小化这个块的数量就行。D题如果猜到......