CF1913B Swap and Delete 題解

心海秋的墨木仄發表於2024-04-10

翻譯

給定一個字串 \(s\),你有兩種操作:

  1. 刪除一個字元。(花費一枚金幣)
  2. 交換某兩個字元的位置。(不花費金幣)

假設經過若干次操作後得到的字串為 \(t\)

\(t\) 是好的當且僅當對於任意的 \(i\)\(1 \le i \le |t|\)\(|t|\) 為字串 \(t\) 的長度),均滿足 \(t_i \ne s_i\)。(\(s\) 是原本的字串)

自然,空串一定是好的。

問最小花費。

多測。

思路

記錄每個 \(s\)01 的數量,第二次遍歷時直接遍歷 \(s\) 串,\(s\) 串為 1 則填 0,為 0 則填 1。當無法繼續填時直接輸出剩餘的 01 總字元數。因為此時後面的不管怎麼填一定會有相同,只能全刪。

程式碼

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#define ll long long
#define fr(i , a , b) for(ll i = a ; i <= b ; ++i)
#define fo(i , a , b) for(ll i = a ; i >= b ; --i)
using namespace std;
ll T;
char s[200005];
signed main()
{
    // freopen("in.in" , "r" , stdin);
    // freopen("out.out" , "w" , stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> T;
    while(T--)
    {
        cin >> s + 1;
        ll len = strlen(s + 1) , num0 = 0 , num1 = 0;
        fr(i , 1 , len)
        {
            if(s[i] == '0')
            {
                num0++;
            }
            else
            {
                num1++;
            }
        }
        fr(i , 1 , len)
        {
            if(s[i] == '0')
            {
                if(num1 == 0)
                {
                    break;
                }
                num1--;
            }
            else
            {
                if(num0 == 0)
                {
                    break;
                }
                num0--;
            }
        }
        cout << num1 + num0 << '\n';
    }
    return 0;
}

相關文章