主思路是把每个字符串出现的字母记录一遍,从后向前扫字母,记录最大前缀和的最小,最后比一遍(可能有点怪,考试时算错时间复杂度了)
#include<bits/stdc++.h>
using namespace std;
#define N 5007
int n,m,T,a,vmin[N][50],vmax[N],vmi[N][N];
char c[N][N];
int main()
{
//freopen("dict.in","r",stdin);
//freopen("dict.out","w",stdout);
scanf("%d%d",&n,&m);
memset(vmax,100,sizeof vmax);
for(int i=1;i<=n;i++)
scanf("%s",c[i]+1);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
{
vmin[i][c[i][j]-96]++;
//printf("%d",vmin[i][c[i][j]-96]);
//vmax[j]=max()
}
}
//for(int i=1;i<=n;i++){
// for(int j=1;j<=26;j++)
// printf("%d ",vmin[i][j]);
// printf("\n");
//}
for(int i=1;i<=n;i++)
{
int k=26,j=1,fl1=0;
while(j<=m)
{
//printf("-%d",c[1][1]);
while(vmin[i][k]==0)k--;
int num=vmin[i][k];
if(fl1==1)
{
while(j<=m)
{
while(vmin[i][k]==0)k--;
num=vmin[i][k];
while(num>0)
vmax[j]=k,j++,num--;
//printf("%d %d %d %d\n",vmin[i][k],k,i,j);
k--;
}
}
else{
while(vmax[j]==k&&num!=0)num--,j++;
if(k>vmax[j]&&fl1==0)break;
if(vmax[j]>k)fl1=1;
}
}
k=1;j=1;
while(j<=m)
{
while(vmin[i][k]==0)k++;
for(int _=1;_<=vmin[i][k];_++)
vmi[i][j]=k,j++;
k++;
//printf("%d %d ",j,k);
}
}
//for(int i=1;i<=m;i++)printf("%d ",vmax[i]);
//for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++)
// printf("%d ",vmi[i][j]);
// printf("\n");
//}
for(int i=1;i<=n;i++){
int fl=0,fl2=1;
for(int j=1;j<=m;j++){
if(vmi[i][j]>vmax[j]){fl2=0;break;}
if(vmi[i][j]<vmax[j])fl=1;
}
if(fl||fl2)printf("1");
else printf("0");
}
return 0;
}