codeforces1509 D. Binary Literature (构造+指针)

简介: codeforces1509 D. Binary Literature (构造+指针)

codeforces1509 D. Binary Literature

原题链接

题意:

给定三个长度为2 ∗ n字符串,要求构造一个长度小于等于3 ∗ n的字符串s 使得至少有两个字符串是s的子序列。

思路:

本来的思路是枚举两个字符串a , b,b中的0 / 1一定在a里出现过,只需要在a后面拼接上b剩下的部分就行。思路会忽略掉一些正确的情况。

由于给出的字符串只有0 , 1所以一定有两个字符串有长度大于n的全0或全1的公共子序列,只需要将字符串中非子序列的部分按次序插入到公共子序列当中就是答案。

感觉不好实现所以去看了题解的第二种思路。

还是由于给出的字符串只有0 , 1两种情况,所以考虑指针的写法:

p a , p b , p c分别指向字符串a , b , c每次比较任意两个,有相同字符则将该字符添加到结果字符串中,同时对应的指针往后移动。由于字符不是0就是1,所以一定会有两个相等。

直到有一个字符串全部被加到结果字符串里。(假设该字符串为a aa,结束的条件为p a > 2 ∗ n)

这时候结果字符串的长度为i d x,所有的指针至少移动了 2 ∗ i d x次。

假设p a指针移动了2*n次,所以剩下的p b , p c指针移动了2 ∗ ( i d x − n )次,也就是说肯定有一个指针至少移动了( i d x − n )次,把这个指针对应的字符串的剩余部分加到结果中即可。

添加的字符最多为2 ∗ n − ( i d x − n ) = 3 ∗ n − i d x

结果字符串的长度最多为i d x + 3 ∗ n − i d x = 3 n

还有个小细节:数组至少要开到3 e 5

代码:

如果用数组存的话,代码会简洁点,下面是我的垃圾代码

const int maxn =1e6+7;
char a[maxn],b[maxn],c[maxn];
char s[maxn];
int main(){
    int T=read;
    while(T--){
      int n=read;
      cin>>a+1>>b+1>>c+1;
      int pa=1,pb=1,pc=1,idx=0;
      while(1){
        if(a[pa]==b[pb]){
          s[++idx]=a[pa];
          pa++,pb++;
          if(pa>2*n||pb>2*n||pc>2*n) break;
          continue;
        } 
        if(b[pb]==c[pc]){
          s[++idx]=b[pb];
          pb++,pc++;
          if(pa>2*n||pb>2*n||pc>2*n) break;
          continue;
        }
        if(a[pa]==c[pc]){
          s[++idx]=a[pa];
          pa++,pc++;
          if(pa>2*n||pb>2*n||pc>2*n) break;
        } 
      }
      ///cout<<pa<<"*****"<<pb<<"****"<<pc<<endl;
      int t=idx-n;
      if(pa>2*n){
        if(pb>t){
          for(int i=pb;i<=2*n;i++)
            s[++idx]=b[i];
          for(int i=1;i<=idx;i++)
            cout<<s[i];
          puts("");
          continue;
        }
        if(pc>t){
          for(int i=pc;i<=2*n;i++)
            s[++idx]=c[i];
          for(int i=1;i<=idx;i++)
            cout<<s[i];
          puts("");
          continue;
        }
      }
      if(pb>2*n){
        if(pa>t){
          for(int i=pa;i<=2*n;i++)
            s[++idx]=a[i];
          for(int i=1;i<=idx;i++)
            cout<<s[i];
          puts("");
          continue;
        }
        if(pc>t){
          for(int i=pc;i<=2*n;i++)
            s[++idx]=c[i];
          for(int i=1;i<=idx;i++)
            cout<<s[i];
          puts("");
          continue;
        }
      }
      if(pc>2*n){
        if(pb>t){
          for(int i=pb;i<=2*n;i++)
            s[++idx]=b[i];
          for(int i=1;i<=idx;i++)
            cout<<s[i];
          puts("");
          continue;
        }
        if(pa>t){
          for(int i=pa;i<=2*n;i++)
            s[++idx]=a[i];
          for(int i=1;i<=idx;i++)
            cout<<s[i];
          puts("");
          continue;
        }
      }
    }
    return 0;
}
目录
相关文章
|
存储 编译器 C++
C++:this指针和构造与析构的运用--2
C++:this指针和构造与析构的运用--2
复制带随机指针的链表【构造链表深拷贝】
复制带随机指针的链表【构造链表深拷贝】
|
存储 C++
C++:this指针和构造与析构的运用--3
C++:this指针和构造与析构的运用--3
|
存储 编译器 C++
C++:this指针和构造与析构的运用--1
C++:this指针和构造与析构的运用--1
|
存储 编译器 C语言
【C++学习】类和对象 | 类的成员函数存放在哪里?| this指针 | 构造函数 | 析构函数 | 探索构造和析构函数的更多细节
【C++学习】类和对象 | 类的成员函数存放在哪里?| this指针 | 构造函数 | 析构函数 | 探索构造和析构函数的更多细节
422 0
|
数据建模
【每日一题Day66】LC1754构造字典序最大的合并字符串 | 贪心 双指针模拟
思路:双指针遍历两个字符串,贪心比较字符的字典顺序,并添加至结果集
134 0
【每日一题Day66】LC1754构造字典序最大的合并字符串 | 贪心 双指针模拟
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
1109 13
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
487 4
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
166 0