• namonamo Daimayuan Online Judge


    题目链接:http://oj.daimayuan.top/course/10/problem/678

     

    dls 桌面上的两个小女孩除了喜欢亲亲以外,还喜欢一起共用一副耳机听歌。

    一天,她们正在听她们最喜欢的歌,一首歌的歌词可以看着一个只包含小写字母的字符串,保证字符串的长度为偶数。

    不幸的是,她们的 eirpods 是拼夕夕九块九包邮的,发生了一些神奇的故障,使得对于每个字母,恰好只有一个人能够听到。

    在一首歌放完后,她们一边抱怨耳机的质量,同时惊奇地发现,她们两个人所听到的字母各自组成的字符串完全相同

    给定一首歌的歌词,判断这种事情是否可能发生。


    形式化题意:给定一个长度是偶数,仅有小写字母构成的字符串,判断是否能被分成两个完全相同的子序列

    输入格式

    第一行一个正整数 TT,表示数据组数。

    接下来每一行一个字符串 SS,表示歌词。

    输出格式

    输出共 TT 行,每行一个字符串 possible 或 impossible,表示该组数据的答案。

    样例输入

    1. 5
    2. aabb
    3. abba
    4. namonamo
    5. arqmpfvvbtltlhufznkldkurrazmgebfxeamrewn
    6. aacfcfqqsmksimkoioeertbrtbhphnpnggddjjll

    样例输出

    1. possible
    2. impossible
    3. possible
    4. impossible
    5. possible

     思路:如果对整个字符串爆搜的话,每次有两个选择,40个字符串,复杂度为2^40显然超时

    那么我们就把他分成两半进行折半搜索,这样复杂度降为2^20大约是1e6,这样就不会超时

    那么我们分别搜前半段和后半段,对每个字符要么给a要么给b

    然后搜完前后两段之后我们在查一下前面半段的a+后面半段的a==前面半段的b+后面半段的b

    例如:

     那么我们可以知道前半段的前缀相等,后半段的后缀相等,前半段多出来的和后半段多出来的中间段相等

    那么我们可以对于每次前半段搜到的a,b,先判断前缀是否相等

    如果相等,就把中间多出来的用set存一下

    然后对于后半段每次搜出来的a,b,先判断他的后缀是否相等

    如果相等的话我们就把他的中间段拿出来看看set里有没有,如果有的话就说明符合s1==s2了

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. typedef long long ll;
    4. typedef pair<int,int> pii;
    5. int gcd(int a,int b) {
    6. return b? gcd(b,a%b):a;
    7. }
    8. /*
    9. int dx[8]={-2,-2,-1,1,2,2,-1,1};
    10. int dy[8]={-1,1,2,2,1,-1,-2,-2};
    11. int dx[4]={0,-1,0,1};
    12. int dy[4]={-1,0,1,0};
    13. int dx[8]={-1,1,0,0,-1,-1,1,1};
    14. int dy[8]={0,0,-1,1,-1,1,-1,1};
    15. */
    16. //int e[N],ne[N],h[N],idx,w[N];
    17. /*void add(int a,int b,int c){
    18. e[idx]=b;
    19. w[idx]=c;
    20. ne[idx]=h[a];
    21. h[a]=idx++;
    22. }
    23. */
    24. const int N=2e5+10;
    25. int n;
    26. bool f;
    27. set<string> ss;
    28. string s;
    29. void dfs1(int st,int end,string &a,string &b){
    30. if(f)return ;
    31. if(st>end){
    32. for(int i=0;i<min(a.size(),b.size());i++){
    33. if(a[i]!=b[i])return ;
    34. }
    35. if(a.size()<b.size()){
    36. ss.insert(b.substr(a.size()));
    37. }else {
    38. ss.insert(a.substr(b.size()));
    39. }
    40. return ;
    41. }
    42. a.push_back(s[st]);
    43. dfs1(st+1,end,a,b);
    44. a.pop_back();
    45. b.push_back(s[st]);
    46. dfs1(st+1,end,a,b);
    47. b.pop_back();
    48. }
    49. void dfs2(int st,int end,string a,string b){
    50. if(f)return ;
    51. if(st>end){
    52. reverse(a.begin(),a.end());
    53. reverse(b.begin(),b.end());
    54. for(int i=0;i<min(a.size(),b.size());i++){
    55. if(a[i]!=b[i])return ;
    56. }
    57. string op;
    58. if(a.size()<b.size()){
    59. op=b.substr(a.size());
    60. }else op=a.substr(b.size());
    61. reverse(op.begin(),op.end());
    62. if(ss.count(op) ){
    63. f=true;
    64. }
    65. return ;
    66. }
    67. a.push_back(s[st]);
    68. dfs2(st+1,end,a,b);
    69. a.pop_back();
    70. b.push_back(s[st]);
    71. dfs2(st+1,end,a,b);
    72. b.pop_back();
    73. }
    74. void sove(){
    75. s.clear();
    76. ss.clear() ;
    77. cin>>s;
    78. f=false;
    79. n=s.size();
    80. s="?"+s;
    81. string a,b;
    82. dfs1(1,n/2,a,b);
    83. dfs2(n/2+1,n,a,b);
    84. if(f)cout<<"possible"<<endl;
    85. else cout<<"impossible"<<endl;
    86. }
    87. signed main(){
    88. ios::sync_with_stdio(false);
    89. cin.tie() ,cout.tie() ;
    90. int t;
    91. cin>>t;
    92. while(t--){
    93. sove();
    94. }
    95. return 0;
    96. }

     

  • 相关阅读:
    Python实现Stacking回归模型(随机森林回归、极端随机树回归、AdaBoost回归、GBDT回归、决策树回归)项目实战
    第三章 ArcGIS Pro创建 python 脚本工具(二)
    如何有效应对差评对亚马逊销量的影响及应对措施
    csdn涨薪技术之Linux 启动流程及相关知识
    【Java筑基】IO流基础之常见工具流和进程通信
    Quartz 建表语句SQL文件
    排序算法-----归并排序
    leetcode(力扣) 509. 斐波那契数 (动态规划入门,模板代码)
    Pulsar【部署 02】Pulsar可视化工具Manager安装使用
    OSG笔记:osgText::Font搜索路径及开发中的应用
  • 原文地址:https://blog.csdn.net/qq_61903556/article/details/127665104