Codeforces - 990C

<Codeforces 990C>

題意:

給n個只由 '(' 和 ')' 組成的串,問從這些串中選出兩個串,使他們括號匹配,能夠成多少個匹配串,自身和自身組合匹配也算。以題中第二個樣例說明:

輸入:2 ( ) ( )

輸出:4

解釋:輸入的兩個串 a,b 分別是 a: ( ),b: ( ),所以共四種連接方式,即 a->a,a->b,b->a,b->b

思路:

說實話,這個思路,就是一種只可意會不可言傳的感覺,我大概用我拙劣的語言,表述一下 T^T

我先對每個輸入進來的串,進行如下操作:

int ln = s.length();
for(int j = 0; j < ln; j++) {
	if(s[j] == '(') l++;
	else {
		if(l) l--;
		else r++;
	}
}

這裏的 l 代表,在輸入進來的這個串中,不能與自身右括號形成匹配的左括號的個數;

r 則代表,在輸入進來的這個串中,不能與自身左括號形成匹配的右括號的個數。

我已經進我最大努力表述了,自行腦補一下這裏有一個笑哭的表情。。。注意聽~

這樣每個串無法在自身形成匹配的左右括號數就分別找出來了。

然後進行如下兩步操作:

if(!l) R[r]++;
if(!r) L[l]++;

以上兩步是核心代碼,我盡我最大努力解釋清楚,

首先明確兩點,

(1)如果某個串裏 l != 0 && r != 0,那這個串沒法和任何一個串進行匹配

(2)有且僅有 x 個左括號不能在自身匹配的串, 它要想配對, 必須找有且僅有 x 個右括號不能在自身匹配的串

這也就是L[ ], R[ ]這兩個數組的作用,如果 l == 0,那就意味着,這個串裏有且僅有 r 個右括號匹配不到 ( r 可以取0),這樣,它就必須找一個,有且僅有 r 個左括號匹配不到的的串,進行匹配。所以我在 l == 0 時,進行R[r]++,就是爲了找到一個L[r]和當前的R[r]進行相乘再加入ans裏,L[ ],R[ ]數組分別代表的值是僅有左括號不匹配,和僅有右括號不匹配的串的個數,而L[i], R[i]中的 i 值,則分別代表不匹配的左右括號各有幾個。r == 0 同理。

本人AC代碼:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <stack>
#include <ctime>
#include <cctype>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 7;
const int Inf = 1e9 + 7;
pair <int, int> a[maxn];
queue <int> qua;
set <int> sst;
vector <int> vect;
map <int, int> mp;
priority_queue < int, vector<int>, less<int> > qua1;
priority_queue < int, vector<int>, greater<int> > qua2;
int n;
string s;
ll L[maxn], R[maxn]; //有pos個左括號不能在自身匹配的串, 它要想配對, 必須找有pos個右括號不能在自身匹配的串
// 而L[pos]和R[pos]記錄的就是左右括號與自身不匹配的串的個數, 即ans += L[pos] * R[pos]
ll ans;

int main() {
	cin >> n;
	int l, r; //記錄每個串中左、右括號無法在該串自身內進行匹配的個數分別爲多少
	for(int i = 1; i <= n; i++) {
		cin >> s;
		l = r = 0;
		int ln = s.length();
		for(int j = 0; j < ln; j++) {
			if(s[j] == '(') l++;
			else {
				if(l) l--;
				else r++;
			}
		}
		if(!l) R[r]++;
		if(!r) L[l]++;
	}
	for(int i = 1; i <= maxn; i++) ans += L[i] * R[i];
	ans += L[0] * R[0]; //自身就匹配的串的個數
	cout << ans << endl;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章