[NC13B]貝倫卡斯泰露
阿新 • • 發佈:2018-07-24
clear def har lse line tel git 折半 ctype
[NC13B]貝倫卡斯泰露
題目大意:
給定\(A_{1\sim n}(n\le40)\),問是否能將\(A\)分解成兩個相同的子序列?
思路:
折半搜索。時間復雜度\(\mathcal O(2^{\frac n2})\)。
源代碼:
#include<set> #include<cstdio> #include<cctype> inline int getint() { register char ch; while(!isdigit(ch=getchar())); register int x=ch^'0'; while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); return x; } const int N=41; const int base=57,mod=1e9+7; typedef long long int64; int n,a[N],b[N],c[N]; std::set<std::pair<int,int> > set; void dfs1(const int &dep) { if(dep==n/2) { int val=0; if(b[0]<=c[0]) { for(register int i=b[0]+1;i<=c[0];i++) { val=((int64)val*base+c[i])%mod; } } else { for(register int i=c[0]+1;i<=b[0];i++) { val=((int64)val*base+b[i])%mod; } } set.insert(std::make_pair(b[0]-c[0],val)); return; } b[++b[0]]=a[dep+1]; if(b[0]>c[0]||b[b[0]]==c[b[0]]) dfs1(dep+1); b[0]--; c[++c[0]]=a[dep+1]; if(c[0]>b[0]||c[c[0]]==b[c[0]]) dfs1(dep+1); c[0]--; } void dfs2(const int &dep) { if(dep==n/2+1) { int val=0; if(b[0]<=c[0]) { for(register int i=c[0];i!=b[0];i--) { val=((int64)val*base+c[i])%mod; } } else { for(register int i=b[0];i!=c[0];i--) { val=((int64)val*base+b[i])%mod; } } if(set.count(std::make_pair(c[0]-b[0],val))) throw 0; return; } b[++b[0]]=a[dep-1]; if(b[0]>c[0]||b[b[0]]==c[b[0]]) dfs2(dep-1); b[0]--; c[++c[0]]=a[dep-1]; if(c[0]>b[0]||c[c[0]]==b[c[0]]) dfs2(dep-1); c[0]--; } int main() { for(register int T=getint();T;T--) { n=getint(); for(register int i=1;i<=n;i++) a[i]=getint(); set.clear(); b[0]=c[0]=0; dfs1(0); try { dfs2(n+1); } catch(...) { puts("Frederica Bernkastel"); continue; } puts("Furude Rika"); } return 0; }
[NC13B]貝倫卡斯泰露