zoukankan      html  css  js  c++  java
  • 【洛谷6908】[ICPC2015 WF] Evolution in Parallel(贪心)

    点此看题面

    • 给定一个字符串(S)(n)个字符串(s_i),首先要求判断是否所有(s_i)都是(S)的子序列。
    • 然后要求把这(n)个字符串分成两组,满足同组中的所有字符串都是子序列关系。
    • (n,|S|,|s_i|le4000)

    贪心

    先将字符串按照长度排个序,然后从短到长考虑每个字符串,维护好两个字符串集合(A,B)

    如果当前字符串无法加入任何集合显然无解。

    如果当前字符串只能加入一个集合就直接加入。

    否则,我们另外维护一个集合(C),先判断当前字符串能否加入集合(C):能加入就加入,否则随便把集合(C)加到某个集合中,把当前字符串加入另外一个集合。(由于每个集合只需要考虑最后一个字符串,因此这里集合的选择没有影响)

    代码:(O(n|s|))

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 4000
    using namespace std;
    int n,A[N+5],B[N+5],C[N+5];string s[N+5];
    I bool cmp(Con string& x,Con string& y) {return x.length()<y.length();}
    I bool Check(CI x,CI y)//判断x是否为y的子序列
    {
    	RI i,j,n=s[x].length(),m=s[y].length();
    	for(i=j=0;i^n;++i,++j) {W(j^m&&s[x][i]^s[y][j]) ++j;if(j==m) return 0;}return 1;
    }
    int main()
    {
    	RI i,j;for(scanf("%d",&n),cin>>s[n+1],i=1;i<=n;++i) cin>>s[i];
    	RI a=0,b=0,c=0,p,q;for(sort(s+1,s+n+1,cmp),i=1;i<=n;++i)//按字符串从短到长考虑
    	{
    		if(p=Check(A[a],i),q=Check(B[b],i),!p&&!q) return puts("impossible"),0;//如果两个集合都无法加入
    		if(p&&q) {if(Check(C[c],i)) C[++c]=i;else {for(j=1;j<=c;++j) A[++a]=C[j];c=0,B[++b]=i;}continue;}//如果两个集合都能加入,判断能否加入集合C
    		if(p) {if(Check(C[c],i)) for(j=1;j<=c;++j) A[++a]=C[j];else for(j=1;j<=c;++j) B[++b]=C[j];c=0,A[++a]=i;}//只能加入集合A,判断C的归宿
    		else {if(Check(C[c],i)) for(j=1;j<=c;++j) B[++b]=C[j];else for(j=1;j<=c;++j) A[++a]=C[j];c=0,B[++b]=i;}//只能加入集合B,判断C的归宿
    	}
    	for(i=1;i<=c;++i) A[++a]=C[i];if(!Check(A[a],n+1)||!Check(B[b],n+1)) return puts("impossible"),0;//清空集合C,检验是否为S的子序列
    	for(printf("%d %d
    ",a,b),i=1;i<=a;++i) cout<<s[A[i]]<<endl;for(i=1;i<=b;++i) cout<<s[B[i]]<<endl;return 0;//输出答案
    }
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    linux进程管理类
    linux关机重启指令
    linux分区及磁盘挂载
    linux的运行级别
    property
    访问限制机制
    类的组合与封装
    继承与派生
    logging模块
    re模块
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu6908.html
Copyright © 2011-2022 走看看