CF1907B YetnotherrokenKeoard 題解

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

比較簡單,建議評橙。

題面

思路

對於每個給定的字串,用兩個大根堆來分別記錄小寫字母與大寫字母,注意這裡記錄時不要記錄大寫的 B 和小寫的 b

每當出現一個 B 時,從記錄大寫字母的大根堆中取出目前最後錄入的大寫字母的位置,標記,接著彈出堆頂元素,標記。小寫字母同理。

以上操作在遍歷一遍字串的情況下可以實現。

最後再遍歷一遍字串,輸出未打標記的字元即可。大寫的 B 和小寫的 b不要輸出

程式碼

記得多測清空!!!!!!

#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;
priority_queue <ll> qx;
priority_queue <ll> qd;
//priority_queue <ll , vector<ll> , greater<ll>> q;
ll T;
char s[1000006];
signed main()
{
	// freopen("in.in" , "r" , stdin);
	// freopen("out.out" , "w" , stdout);
	scanf("%lld" , &T);
	while(T--)
	{
		while(!qx.empty())
		{
			qx.pop();
		}
		while(!qd.empty())
		{
			qd.pop();
		}
		scanf("%s" , s + 1);
		ll len = strlen(s + 1);
		fr(i , 1 , len)
		{
			qx.push(-i);
			qd.push(-i);
			if(s[i] >= 'a' && s[i] <= 'z' && s[i] != 'b')
			{
				qx.push(i);
			}
			else if(s[i] >= 'A' && s[i] <= 'Z' && s[i] != 'B')
			{
				qd.push(i);
			}
			if(s[i] == 'b')
			{
				ll del = qx.top();
				qx.pop();
				if(del >= 0)
				{
					s[del] = '!';
				}
				s[i] = '!';
			}
			if(s[i] == 'B')
			{
				ll del = qd.top();
				qd.pop();
				if(del >= 0)
				{
					s[del] = '!';
				}
				s[i] = '!';
			}
		}
		fr(i , 1 , len)
		{
			if(s[i] == '!')
			{
				continue;
			}
			cout << s[i];
		}
		cout << '\n';
	}
	return 0;
}