1. 程式人生 > 其它 >Codeforces Round #790 (Div. 4) A - H 題解

Codeforces Round #790 (Div. 4) A - H 題解

傳送門

上次打了一場校賽,剛好和上次的 div2 衝了,最近又各種 ddl 轟炸,搞得沒啥時間寫題解

這場打下來感覺就是各種模板題

A. Lucky?

直接寫,前三個數字的和等於後三個數字的和

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int a = 0, b = 0;
    for(int i=0; i<3; i++)
    {
        int x;
        scanf("%1d", &x);
        a += x;
    }
    for(int i=0; i<3; i++)
    {
        int x;
        scanf("%1d", &x);
        b += x;
    }
    if(a == b) cout << "yes" << endl;
    else cout << "no" << endl;
    }

    return 0;
}

B. Equal Candies

直接找到陣列的最小的,然後遍歷一次看看其他都要拿走多少

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        int minn = 1e9 + 7;
        ll ans = 0;
        for(int i=0; i<n; i++)
        {
            ll x;
            cin >> x;
            minn = x < minn ? x : minn;
            ans += x;
        }
        cout << ans - minn * n << endl;
    }

    return 0;
}

C. Most Similar Words

直接暴力跑一遍,代價的話就是兩個字母直接相減的絕對值

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
string s[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n, m;
        cin >> n >> m;
        for(int i=0; i<n; i++)
            cin >> s[i];
        int ans = m * 26;
        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                int now = 0;
                for(int k=0; k<m; k++)
                {
                    int x = s[i][k] - s[j][k];
                    if(x < 0) x = -x;
                    now += x;
                }
                ans = now < ans ? now : ans;
            }
        }
        cout << ans << endl;
    }

    return 0;
}

D. X-Sum

類似於 N 皇后的狀態儲存,處理斜邊的和,左斜就是 x - y,右斜就是 x + y,然後陣列開大點就行

最後遍歷每一個點,代價是所屬的兩個斜邊的和 減去 自身的重複

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 210;
const ll inf = 1e17 + 10;
ll num[maxn][maxn];
ll l[maxn * 4], r[maxn * 4];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n, m;
        cin >> n >> m;
        for(int i=0; i<n; i++) for(int j=0; j<m; j++) cin >> num[i][j];
        for(int i=0; i<maxn * 4; i++) l[i] = r[i] = 0;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                l[200 + i - j] += num[i][j];
                r[i + j] += num[i][j];
            }
        }
        ll ans = 0;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                ll now = l[200 + i - j] + r[i + j] - num[i][j];
                ans = now > ans ? now : ans;
            }
        }
        cout << ans << endl;
    }

    return 0;
}

E. Eating Queries

二分板子題

排序後做字首和,直接二分查詢

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll num[maxn];

bool cmp(ll a, ll b)
{
    return a > b;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n, m;
        cin >> n >> m;
        for(int i=1; i<=n; i++) {cin >> num[i];}
        sort(num + 1, num + 1 + n, cmp);
        for(int i=1; i<=n; i++) num[i] += num[i-1];
        num[n + 1] = inf;
        while(m--)
        {
            ll x;
            cin >> x;
            ll way = lower_bound(num + 1, num + n + 2, x) - num;
            if(way == n + 1) way = -1;
            cout << way << endl;
        }
    }

    return 0;
}

F. Longest Strike

這題做的時候卡了半小時

直接用 map 裝起來,然後遍歷一次,不連續或者小於 k 就斷開,然後記錄最長是多少

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
map<int, int>vis;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n, m;
        cin >> n >> m;
        for(int i=0; i<n; i++)
        {
            int x;
            cin >> x;
            vis[x]++;
        }
        int way = 0, now = 0, maxx = 0, ans = 0;
        for(auto it=vis.begin(); it!=vis.end(); it++)
        {
            if(now != it->first)
            {
                way = 0;
                now = it->first;
            }
            if(it->second < m)
                way = 0;
            else
            {
                way++;
                if(way > maxx)
                {
                    maxx = way;
                    ans = it->first;
                }
            }
            now++;
        }
        if(maxx == 0) cout << "-1" << endl;
        else cout << ans - maxx + 1 << " " << ans << endl;
        vis.clear();

    }

    return 0;
}

G. White-Black Balanced Subtrees

簡單樹型 dp 模板題

從根開始搜,當前樹的黑白,通過先搜尋子樹的黑白數量,然後加起來,最後判斷一下當前樹是否符合平衡

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 4010;
const ll inf = 1e17 + 10;
vector<int>gra[maxn];
int l[maxn], r[maxn];
string s;

int dps(int now, int pre)
{
    int ans = 0;
    if(s[now-1] == 'W') l[now]++;
    else r[now]++;
    for(int i=0; i<gra[now].size(); i++)
    {
        int nex = gra[now][i];
        if(nex == pre) continue;
        ans += dps(nex, now);
        l[now] += l[nex];
        r[now] += r[nex];
    }
    return ans + (l[now] == r[now]);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for(int i=0; i<=n; i++) {l[i] = r[i] = 0; gra[i].clear();}
        for(int i=2; i<=n; i++)
        {
            int x;
            cin >> x;
            gra[x].push_back(i);
        }
        cin >> s;
        cout << dps(1, 1) << endl;
    }

    return 0;
}

H. Maximum Crossings

題目模型轉化過來就是求逆序對

考慮樹狀陣列 或者 歸併排序 \(O(nlogn)\)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <functional>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <deque>
#include <stack>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
const ll maxn = 2e5 + 10;
const ll inf = 1e17 + 10;
ll tr[maxn];
int n;

inline int lowbit(int x)
{
    return x & (-x);
}

void add(int x, ll val)
{
    for(int i=x; i<=n; i+=lowbit(i))
        tr[i] += val;
}

ll query(int x)
{
    ll ans = 0;
    while(x)
    {
        ans += tr[x];
        x -= lowbit(x);
    }
    return ans;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        cin >> n;
        for(int i=0; i<=n; i++) tr[i] = 0;
        ll ans = 0;
        for(int i=0; i<n; i++)
        {
            ll x;
            cin >> x;
            ans += i - query(x - 1);
            add(x, 1);
        }
        cout << ans << endl;
        
    }

    return 0;
}