HDU 5745 La Vie en rose(简单模拟)

题目链接:HDU 5745


题面:

La Vie en rose

Time Limit: 14000/7000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 567    Accepted Submission(s): 285


Problem Description
Professor Zhang would like to solve the multiple pattern matching problem, but he only has only one pattern string p=p1p2...pm . So, he wants to generate as many as possible pattern strings from p using the following method:

1. select some indices i1,i2,...,ik such that 1i1<i2<...<ik<|p| and |ijij+1|>1 for all 1j<k .
2. swap pij and pij+1 for all 1jk .

Now, for a given a string s=s1s2...sn , Professor Zhang wants to find all occurrences of all the generated patterns in s .
 

Input
There are multiple test cases. The first line of input contains an integer T , indicating the number of test cases. For each test case:

The first line contains two integers n and m (1n105,1mmin{5000,n}) -- the length of s and p .

The second line contains the string s and the third line contains the string p . Both the strings consist of only lowercase English letters.
 

Output
For each test case, output a binary string of length n . The i -th character is "1" if and only if the substring sisi+1...si+m1 is one of the generated patterns.
 

Sample Input
  
  
3 4 1 abac a 4 2 aaaa aa 9 3 abcbacacb abc
 

Sample Output
  
  
1010 1110 100100100
 

Author
zimpha


题意:

    问给定一个原串,一个模式串,原串任意位置的一段连续子串是否能通过交换任意相邻两位得到,可以则输出1,不可以则输出0。


解题:

    这题,纯暴力就能过,复杂度看似悬,但很难出数据卡住,或者可以理论上证明,是卡不住的,加一个前缀和的预判,大概能优化1s。如果,当前位和模式串位不同,只能和后一位交换,此时下标加2,若不能交换,则代表不行。


代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long
#define sz 100005
using namespace std;
char s[sz],p[5005];
int num[sz][26],cnt[26];
int n,m;
int main()
{
    int t,n,m;
	bool flag;
	scanf("%d",&t);
	while(t--)
	{
       scanf("%d%d",&n,&m);
	   scanf("%s",s);
       scanf("%s",p);
	   memset(cnt,0,sizeof(cnt));
	   for(int i=0;i<26;i++)
		   num[0][i]=0;
	   for(int i=1;i<=n;i++)
	   {
		   for(int j=0;j<26;j++)
			   num[i][j]=num[i-1][j];
		   num[i][s[i-1]-'a']++;
	   }
       for(int i=0;i<m;i++)
		   cnt[p[i]-'a']++;
	   for(int i=0;i<=n-m;i++)
	   { 
		   flag=1;
		   for(int j=0;j<26;j++)
		   {
			   if(cnt[j]!=num[i+m][j]-num[i][j])
			   {
				   flag=0;
				   break;
			   }
		   }
		   if(flag)
		   {
			   for(int j=0;j<m;j++)
			   {
				   if(s[i+j]==p[j])
					   continue;
				   else
				   {
					   if(j==m-1)
					   {
						   flag=0;
						   break;
					   }
					   if(s[i+j]==p[j+1]&&s[i+j+1]==p[j])
					   {
						   j++;
					   }
					   else
					   {
						   flag=0;
						   break;
					   }
				   }
			   }
		   }
		   if(flag)
			   printf("1");
		   else
			   printf("0");
	   }
	   for(int i=1;i<m;i++)
		   printf("0");
	   printf("\n");
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值