Codeforces Round 916 (Div. 3)

什么时候才能不困發表於2024-07-10

A. Problemsolving Log

簽到題,對於給出的字串,記錄每個字母出現的次數,然後遍歷一遍,如果對應的字母出現的次數大於它的位次,則說明該題被解出來了,最後輸出解題數量即可

點選檢視程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<queue>
#include<set>
using namespace std;
typedef long long ll;
const int N = 2*1e5 + 10;
void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    int st[27] = { 0 };
    int count = 0;
    for (int i = 0; i < s.size(); i++)
    {
        st[s[i] - 'A' + 1]++;
    }
    for (int i = 1; i < 27; i++)
    {
        if (st[i] >= i) count++;
    }
    cout << count << endl;
}

int main() {
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

B. Preparing for the Contest

排序問題,興奮 \(k\) 次,即前 \(1-k\) 按照升序排列,剩下的按照降序排序即可

點選檢視程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
ll gcd(ll x, ll y) {            //最大公約數
    while (y ^= x ^= y ^= x %= y);
    return x;
}
ll lcm(ll x, ll y) {           //最小公倍數
    return x * y / gcd(x, y);
}
void solve() {
    int x, k;
    cin >> x >> k;
    int no = 0;
    for (int i = 1; i<=x; i++)
    {
        if (k != 0)
            cout << i << " ";
        else
        {
            no = i;
            break;
        }
        k--;
    }
    for (int i = x; i >= no; i--)
    {
        cout << i << " ";
    }
    cout << endl;
}

int main() {
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

C. Quests

暴力貪心,先用字首和預處理陣列 \(a\) ,之後對於陣列 \(b\) ,用一個陣列 \(d[i]\) 表示前 \(i\) 箇中最大的 \(b\) ,最後遍歷一遍, \(ans\) 取最大的 \(c[i] + (y-i)\times d[i]\)

點選檢視程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
ll gcd(ll x, ll y) {            //最大公約數
    while (y ^= x ^= y ^= x %= y);
    return x;
}
ll lcm(ll x, ll y) {           //最小公倍數
    return x * y / gcd(x, y);
}
void solve() {
    ll x, y;
    cin >> x >> y;
    vector<ll>a(x+1);
    vector<ll>b(x+1);
    vector<ll>c(x + 1);
    vector<ll>d(x + 1);
    d[0] = 0;
    c[0] = 0;
    ll ans = 0;
    for (int i = 1; i <=x; i++)
    {
        cin >> a[i];
        c[i] = a[i] + c[i - 1];//字首和
       // cout << c[i] <<" ";
    }
    for (int i = 1; i <=x; i++)
    {
        cin >> b[i];
        d[i] = max(d[i - 1], b[i]);//最大
    }
    for (int i = 1; i <=min(x,y); i++)
    {
        ll sum = c[i] + (y - i) * d[i];
        //cout << sum << " ";
        ans = max(ans, sum);
    }
    cout << ans << endl;
}

int main() {
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

D. Three Activities

暴力打表,先將每一個活動都排序(找出最多人數的3天),然後這3天互相排列組合,去除天數相同的,剩下的找最大值即是答案

點選檢視程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll gcd(ll x, ll y) {            //最大公約數
    while (y ^= x ^= y ^= x %= y);
    return x;
}
ll lcm(ll x, ll y) {           //最小公倍數
    return x * y / gcd(x, y);
}
struct no {
    ll num;
    ll day;
}a[N],b[N],c[N];

bool cmp(no x, no y)
{
    return x.num > y.num;
}
void solve() {
    ll x;
    cin >> x;
    for (int i = 0; i < x; i++)
    {
        cin >> a[i].num;
        a[i].day = i;
    }
    for (int i = 0; i < x; i++)
    {
        cin >> b[i].num;
        b[i].day = i;
    }
    for (int i = 0; i < x; i++)
    {
        cin >> c[i].num;
        c[i].day = i;
    }
    sort(a, a + x, cmp);
    sort(b, b + x, cmp);
    sort(c, c + x, cmp);//由大到小排序
    ll ans = 0;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            for (int k = 0; k < 3; k++)
            {
                if (a[i].day != b[j].day && a[i].day != c[k].day && b[j].day != c[k].day)
                    ans = max(a[i].num + b[j].num + c[k].num, ans);
            }
        }
    }
    cout << ans << endl;
}

int main() {
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

E. Game with Marbles

貪心排序問題,這一題 \(easy\)\(hard\) 差別不大, \(easy\) 應該暴力模擬可以過。計算每一組的權值, \(Alice\) (簡稱 \(A\) ), \(Bob\) (簡稱 \(B\) ) 對於 \(A\) 來說,選擇的一組所獲得的權值是 \(a_i+b_i-1\) (消除 \(b_i\) 等於加 \(b_i\)\(B\) 拉開了 \(b_i\) 的差距且保留了自己的剩餘的 \(a_i-1\) ,因此是 \(a_i+b_i-1\) );同理,對於 \(B\) 來說,也是這樣,因此無論是 \(A\) 操作時還是 \(B\) 操作時,所選擇的都是 \(a_i+b_i\) 最大值那一組 (每一組的權值都有 -1 因此可以僅比較 \(a_i+b_i\)) , 使用結構體儲存每一組石子的數量和和組號,對石子數量進行排序,之後由大到小進行模擬即可。

點選檢視程式碼
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
ll gcd(ll x, ll y)
{            //最大公約數
    while (y ^= x ^= y ^= x %= y);
    return x;
}
ll lcm(ll x, ll y) {           //最小公倍數
    return x * y / gcd(x, y);
}
struct non {
    ll num;
    ll step;
}v[10];
bool cmp(non x, non y) {
    return x.num < y.num;
}

void solve() {
    ll x;
    cin >> x;
    vector<ll>a(x + 1);
    vector<ll>b(x + 1);
   // vector<ll>v(x + 1);
    for (int i = 0; i < x; i++)
    {
        cin >> a[i];
    }
    for (int i = 0; i < x; i++)
    {
        cin >> b[i];
    }
    for (int i = 0; i < x; i++)
    {
        v[i].num = a[i] + b[i] - 1;
        v[i].step = i;
    }
    sort(v, v + x,cmp);
    //for (int i = 0; i < x; i++)
    //{
    //    cout << v[i].num << " ";
    //}
    ll sum = 0;
    int j = 1;
    if (x % 2 == 0)
    {
        for (int i = x-1; i>=0; i--)
        {
            //cout << v[i] << " ";
            if (j == 1)
            {
                sum += a[v[i].step] - 1;
            }
            else
                sum -= b[v[i].step] - 1;
            j *= -1;
        }
    }
    else
    {
        for (int i = x - 1; i >= 0; i--)
        {
            if (i ==0)
            {
                sum += a[v[i].step] - 1;
                break;
            }
            else
            {
                if (j == 1)
                {
                    sum += a[v[i].step] - 1;
                }
                else
                    sum -= b[v[i].step] - 1;
            }
            j *= -1;
        }
    }
    cout << sum << endl;
}

int main() {
    int t;
    cin >> t;
    while (t--)
        solve();
    return 0;
}

相關文章