题目链接:http://oj.daimayuan.top/course/10/problem/678
dls 桌面上的两个小女孩除了喜欢亲亲以外,还喜欢一起共用一副耳机听歌。
一天,她们正在听她们最喜欢的歌,一首歌的歌词可以看着一个只包含小写字母的字符串,保证字符串的长度为偶数。
不幸的是,她们的 eirpods 是拼夕夕九块九包邮的,发生了一些神奇的故障,使得对于每个字母,恰好只有一个人能够听到。
在一首歌放完后,她们一边抱怨耳机的质量,同时惊奇地发现,她们两个人所听到的字母各自组成的字符串完全相同。
给定一首歌的歌词,判断这种事情是否可能发生。
形式化题意:给定一个长度是偶数,仅有小写字母构成的字符串,判断是否能被分成两个完全相同的子序列。
输入格式
第一行一个正整数 TT,表示数据组数。
接下来每一行一个字符串 SS,表示歌词。
输出格式
输出共 TT 行,每行一个字符串 possible
或 impossible
,表示该组数据的答案。
样例输入
5
aabb
abba
namonamo
arqmpfvvbtltlhufznkldkurrazmgebfxeamrewn
aacfcfqqsmksimkoioeertbrtbhphnpnggddjjll
样例输出
possible
impossible
possible
impossible
possible
思路:如果对整个字符串爆搜的话,每次有两个选择,40个字符串,复杂度为2^40显然超时
那么我们就把他分成两半进行折半搜索,这样复杂度降为2^20大约是1e6,这样就不会超时
那么我们分别搜前半段和后半段,对每个字符要么给a要么给b
然后搜完前后两段之后我们在查一下前面半段的a+后面半段的a==前面半段的b+后面半段的b
例如:
那么我们可以知道前半段的前缀相等,后半段的后缀相等,前半段多出来的和后半段多出来的中间段相等
那么我们可以对于每次前半段搜到的a,b,先判断前缀是否相等
如果相等,就把中间多出来的用set存一下
然后对于后半段每次搜出来的a,b,先判断他的后缀是否相等
如果相等的话我们就把他的中间段拿出来看看set里有没有,如果有的话就说明符合s1==s2了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int gcd(int a,int b) {
return b? gcd(b,a%b):a;
}
/*
int dx[8]={-2,-2,-1,1,2,2,-1,1};
int dy[8]={-1,1,2,2,1,-1,-2,-2};
int dx[4]={0,-1,0,1};
int dy[4]={-1,0,1,0};
int dx[8]={-1,1,0,0,-1,-1,1,1};
int dy[8]={0,0,-1,1,-1,1,-1,1};
*/
//int e[N],ne[N],h[N],idx,w[N];
/*void add(int a,int b,int c){
e[idx]=b;
w[idx]=c;
ne[idx]=h[a];
h[a]=idx++;
}
*/
const int N=2e5+10;
int n;
bool f;
set<string> ss;
string s;
void dfs1(int st,int end,string &a,string &b){
if(f)return ;
if(st>end){
for(int i=0;i<min(a.size(),b.size());i++){
if(a[i]!=b[i])return ;
}
if(a.size()<b.size()){
ss.insert(b.substr(a.size()));
}else {
ss.insert(a.substr(b.size()));
}
return ;
}
a.push_back(s[st]);
dfs1(st+1,end,a,b);
a.pop_back();
b.push_back(s[st]);
dfs1(st+1,end,a,b);
b.pop_back();
}
void dfs2(int st,int end,string a,string b){
if(f)return ;
if(st>end){
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
for(int i=0;i<min(a.size(),b.size());i++){
if(a[i]!=b[i])return ;
}
string op;
if(a.size()<b.size()){
op=b.substr(a.size());
}else op=a.substr(b.size());
reverse(op.begin(),op.end());
if(ss.count(op) ){
f=true;
}
return ;
}
a.push_back(s[st]);
dfs2(st+1,end,a,b);
a.pop_back();
b.push_back(s[st]);
dfs2(st+1,end,a,b);
b.pop_back();
}
void sove(){
s.clear();
ss.clear() ;
cin>>s;
f=false;
n=s.size();
s="?"+s;
string a,b;
dfs1(1,n/2,a,b);
dfs2(n/2+1,n,a,b);
if(f)cout<<"possible"<<endl;
else cout<<"impossible"<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie() ,cout.tie() ;
int t;
cin>>t;
while(t--){
sove();
}
return 0;
}