1. 程式人生 > >【NOIP2018模擬賽2018.10.23】字串

【NOIP2018模擬賽2018.10.23】字串

字串(string)

【題目描述】 定義兩個字串A,B相似當且僅當滿足以下兩個條件中的至少一個: (1)A和B相同; (2)將A分為長度相同的兩個子串A0,A1,將B分為長度相同的兩個子串B0,B1,滿足A0相似於B0,A1相似於B1或A0相似於B1,A1相似於B0。 給定兩個字串S,T,問它們是否相似。 有多組資料。

【輸入資料】 第一行一個整數t表示資料組數。 每組資料第一行一個字串S,第二行一個字串T,保證它們長度相同。

【輸出資料】 每組資料一行,若相似輸出YES,不相似輸出NO。

【樣例輸入】

2

abab

baab

aabb

abab

【樣例輸出】

YES

NO

【資料範圍】

對於30%的資料,|S|<=30。

對於60%的資料,|S|<=100。

對於100%的資料,t<=30,∑|S|<=500000。

---------------------------------------------------------------------------------------------------------------------------------------------------------------

 做法:分治

拿到這道題都知道可以寫個遞迴二分。本蒟蒻和另外倆個蒟蒻一起打掛了這道題,爆零。迷之RE還調了一個半小時orz。。。。

具體來說就二分判斷,對每一個子串都進行同樣的操作,注意可以換位比較(就是題目中b1 == a0,b0 == a1也可以)

程式碼:

#include<bits/stdc++.h> 
using namespace std; 
int t; string a,b; 
int check(int l1,int r1,int l2,int r2)
{ 
	int len = r1-l1+1; 
	for(int i = 0;i < len;i++)
	{ 
		if(a[i+l1-1] != b[i+l2-1]) goto next; 
	} 
	return 1; 
next:
	if(len%2) return 0; 
	int half = len/2; 
	if(check(l1,l1+half-1,l2,l2+half-1) && check(l1+half,r1,l2+half,r2)
	|| check(l1+half,r1,l2,l2+half-1) && check(l1,l1+half-1,l2+half,r2)) return 1; 
	return 0; 
} 
int main()
{ 
	cin >> t; 
	while(t--)
	{ 
		cin >> a >> b; 
		int n = a.length(); 
		cout << (check(1,n,1,n) ?  "YES" : "NO") << endl; 
	} 
}