nowcoder3274D binary

题目链接

problem

给定一个01串s,定义rev(x)表示逐位翻转(0变1,1变0)x后并删去前导零后所得到的串。好的串定义如下:
s是好的串
如果x是好的串,则rev(x)也是好的串
如果a,b是好的串,则a+b(a,b按顺序拼接)也是好的串
你需要判断串t是否为好的
s,t保证不含前导零

solution

将s不断翻转,直到消失,中间过程中得到的串都是好的。这个比较显然。

然后将上面得到的某个串(假设为a)分别翻转(但是保留前导0)得到b,那么b也是好的。因为如果我们再拼接的时候想拼接上一个b串,那么就可以先在之前的串上加一个形如\(111000\)的串,然后rev一下,然后拼接上a,然后rev一下。这样就可以拼接上一个b串了。

具体实现,因为可以\(n^2\)dp。为了方便操作,可以先将s和t都反过来。这样所有的后缀就都变成了前缀。用\(f[i]\)表示前i个串是否可以拼接出来。如果\(f[i]\)可以拼接出来的话,那么就枚举一个\(j\in[1,n](n为s长度)\)。看\(t_i...t_{i+j}\)是否可以通过上述方式得到,并且更新f[i+j]的值即可。

code

/*
* @Author: wxyww
* @Date:   2019-12-21 08:07:44
* @Last Modified time: 2019-12-21 08:18:05
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 1010;
ll read() {
	ll x = 0,f = 1;char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1; c = getchar();
	}
	while(c >= '0' && c <= '9') {
		x = x * 10 + c - '0'; c = getchar();
	}
	return x * f;
}
char s[N],t[N];
int f[N];
int main() {
	int T = read();
	while(T--) {
		scanf("%s",s + 1);
		scanf("%s",t + 1);
		int n = strlen(s + 1),m = strlen(t + 1);
		memset(f,0,sizeof(f));
		reverse(s + 1,s + n + 1);
		reverse(t + 1,t + m + 1);
		f[0] = 1;

		for(int i = 0;i < m;++i) {
			if(!f[i]) continue;
			int k = t[i + 1] ^ s[1];
			for(int j = 1;j <= n && i + j <= m;++j) {
				if((s[j] ^ t[i + j]) != k) break;
				if(s[j] != s[j + 1]) f[i + j] = 1;
			}
		}
		puts(f[m] ? "YES" : "NO");

	}

	return 0;
}
posted @ 2019-12-21 08:43  wxyww  阅读(187)  评论(0编辑  收藏  举报