ACM-ICPC沈阳区域赛B

给你一堆字符串,编号从1到n,要求输出它上面所有字符串不全是它子串的最大位置,如果没有输出-1

主要就是KMP,每次在上面找到一个不匹配的子串就把位置记录下来,匹配时只匹配记录位置的子串和它前一个子串,如果记录位置的子串再后来被匹配成功了就消除这个位置。

样例

4

5

ab

abc

zabc

abcd

zabcd

4

you

lovinyou

aboutlovinyou

allaboutlovinyou

5

de

def

abcd

abcde

abcdef

3

a

bc

ccc

输出

Case #1: 4

Case #2: -1

Case #3: 4

Case #4:3

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

int _next[2100];
char s[505][2100];
int lena,lenb;
int num[505],l;

void getnext(int tt)
{
	int i=0,j=-1;
	_next[0]=-1;
	while(i<lenb)
	{
		if(j==-1||s[tt][i]==s[tt][j])
		_next[++i]=++j;
		else 
		j=_next[j];
	}
}

int main()
{
	int T;
	scanf("%d",&T);
	for(int k=1;k<=T;k++)
	{
		int n;
		scanf("%d",&n);
		int ok=-1;//ok means the final answer 
		bool flag=false;//判断是否输出-1 
		l=0;//l代表不匹配的字符串数 
		for(int i=0;i<n;i++)
		{
			scanf("%s",s[i]);
			num[l+1]=i-1;//num储存不匹配的字符串的位置,num[]==-1时代表原来不匹配的在后来可以匹配了 
			if(i>1)
			for(int ka=1;ka<=l+1;ka++)//不知道为什么当时写的KMP函数一直调用不了,遂直接写到主函数里 
			{
				int j=num[ka];
				if(j==-1) continue;
				memset(_next,0,sizeof(_next));
				lena=strlen(s[i]);
				lenb=strlen(s[j]);
				
				int ans;
				int tb=j,ta=i;
				int ti=0,tj=0;
				getnext(tb);
				while(ti<lena&&tj<lenb)
				{
					if(tj==-1||s[ta][ti]==s[tb][tj])
					{
						ti++;
						tj++;
					}
					else
					tj=_next[tj];
				}
				if(tj<lenb&&ti==lena)
				{
					ans=-1;
					flag=true;//有一个不匹配就不会输出-1 
					num[++l]=i-1;
					ok=i+1;
					break;
				}	
				else
				{
					ans=1;
					num[ka]=-1;
				}
			}
		}
		printf("Case #%d: ",k);
		if(flag==false)
		printf("-1\n");
		else printf("%d\n",ok);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值