考试ac,民间数据第7个点炸了,求hack(n*m)
查看原帖
考试ac,民间数据第7个点炸了,求hack(n*m)
310929
王思远123456楼主2023/11/30 13:47

主思路是把每个字符串出现的字母记录一遍,从后向前扫字母,记录最大前缀和的最小,最后比一遍(可能有点怪,考试时算错时间复杂度了)

#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;
}
2023/11/30 13:47
加载中...