zoukankan      html  css  js  c++  java
  • AtCoder Regular Contest 119 (ABC题)

    比赛链接:Here

    A - 119 × 2^23 + 1

    注意到 (2^{60} > 10^{18})​ ,所以我们可以直接枚举 (0) ~ (59)

    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        ll n; cin >> n;
        ll ans = (1ll << 60);
        for (int i = 0; i < 60; ++i) {
            ll a = n / (1ll << i);
            ll b = i;
            ll c = n - a * (1ll << i);
            ans = min(ans, a + b + c);
        }
        cout << ans;
    }
    

    B - Electric Board

    给定长度为 (n) 两个字符串 (S,T)​,要求通过最少的操作数把 (S) 变成 (T),操作就是对于 (s_l=0∧s_{l+1}=...=s_r=1) 或者 (s_l=1∧s_{l+1}=...=s_r=0) 可以交换元素 (s_l)(s_r)

    (2≤n≤500000)

    解法1

    我们可以把所有 (0) 换到应该的位置上,那么 (1) 也就确定了。

    (0) 换过去的代价是路上 (0) 的数量,这就和 (1) 没关系了,那么我们把 (S,T)(0) 都取出来,相邻的配对即可。

    解法2

    我们可以把所以 (1) 换到应该的位置上,那么 (0) 也就是确定了。

    (1) 换过去的代价是路上 (0) 的数量,这和 (0/1) 都有关系,直接匹配是行不通的,正确的做法是从左往右扫,如果遇到 (S)(1) 但是 (T) 没有就把他移动到右边第一个 (0),如果 (T)(1) 但是 (S) 没有也把他移动到右边第一个 (0)

    这种做法的正确性有二:一是两个状态都往中间靠拢;二是我们永远在不得不操作的时候操作

    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        int n;
        string s, t;
        cin >> n >> s >> t;
        vector<int>a, b;
        for (int i = 0; i < n; ++i) {
            if (s[i] == '0') a.push_back(i);
            if (t[i] == '0') b.push_back(i);
        }
        if (int(a.size() != int(b.size()))) {cout << -1; return 0;}
        int ans = 0;
        for (int i = 0; i < int(a.size()); ++i)
            if (a[i] != b[i]) ans++;
        cout << ans;
    }
    

    C - ARC Wrecker 2

    (n) 个楼房,第 (i) 个高为 (a_i),相邻的楼房可以同时增加或同时减少,问能够推平(高度全部变成 (0))的区间有多少个。

    (2≤n≤300000,1≤ai≤10^9)

    解法

    一定要有敏锐的观察能力,这道题的结论是:如果奇偶位置高度相同则可以推平

    证明不难,因为无论怎么操作奇偶的差都是不变的,而目标奇偶差值为 (0),初始状态一定能到目标状态。

    然后搞一个特殊的前缀和,奇数位置符号为正,偶数位置符号为负,找权值和为 (0) 的区间即可。

    const int N = 3e5 + 10;
    ll n, ans, a[N];
    map<ll, ll>mp;
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i];
            if (i > 1) a[i] += a[i - 2];
        }
        mp[0] = mp[a[1]] = 1;
        for (int i = 1; i <= n / 2; ++i) {
            int x = 2 * i;
            ans += mp[a[x - 1] - a[x]];
            if (x < n) ans += mp[a[x + 1] - a[x]];
            mp[a[x - 1] - a[x]]++;
            mp[a[x + 1] - a[x]]++;
        }
        cout << ans;
    }
    

    ll a[1 << 19], b[1 << 19], c[1 << 19];
    map<ll, ll>d;
    int main() {
        cin.tie(nullptr)->sync_with_stdio(false);
        ll n, ans = 0;
        cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        for (int i = 1; i <= n; ++i) {
            if (i & 1) b[i] = a[i];
            else b[i] = -a[i];
            c[i] = c[i - 1] + b[i];
        }
        for (int i = 0; i <= n; ++i) {
            ans += d[c[i]];
            d[c[i]] += 1;
        }
        cout << ans;
    }
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    知识点小结
    体检套餐
    序列化和反序列化
    深入.NET平台的软件系统分层开发
    深入.NET平台和C#编程
    影院售票系统
    面向服务(接口)开发过程中常用的实体类数据复制解决方案
    EF优缺点的理解
    事务锁兼容性
    ASP.NET列表信息以Excel形式导出
  • 原文地址:https://www.cnblogs.com/RioTian/p/15107844.html
Copyright © 2011-2022 走看看