众所周知,绩点王(以下简称王)是集训队中的学神,因为他的绩点总是满的。
一天晚上,王做了一个奇奇怪怪的梦。在这个奇奇怪怪的梦里,绩点是以一串01
串表示的。而王则拥有两种神奇的魔法可以改变自己的绩点。
魔法 1 :使用此魔法时,王可以去掉当前绩点的最左边的第一个数。
魔法
2
:使用此魔法时,王可以在当前绩点的最右边增加一个数
x
。其中,若当前绩点的01
串中,1
的个数为奇数,那么
x=1
;若1
的个数为偶数,那么
x=0
。
假设王的绩点以 A 串表示,王想得到的绩点以 B 串表示。王想知道,能否通过使用以上两种魔法,使得自己的绩点变为 B 。(魔法的使用次数不限)
Input
第一行输入一个 T ,表示测试数据组数。 (T≤1000)
每一组测试数据包括两行。
第一行包含一个01
串,表示王的绩点
A
。
第二行包含一个01
串,表示王希望得到的绩点
B
。
(01
串的长度均不超过
1000
)
Output
每组测试数据的输出包含一行,如果能,则输出YES
,否则,输出NO
。
Sample input and output
Sample Input | Sample Output |
---|---|
2 01011 0110 0011 1110 | YES NO |
Hint
第一组数据中,王可以先使用两次魔法
1
,将绩点变为011
,再使用一次魔法
2
,将绩点变为0110
。
第二组数据中,王无法将绩点变为王想要的绩点。
解析
规律题。设A中1的个数为s1,B中1的个数为s2
发现规律:
规律一:当s1偶数时,就不能再向A加1进去了,当s1奇数时,可以再向A加一个1进去(又变成了偶数个1,不能再加)。
所以
1.当s1偶数时s2不能超过s1
2.当s1奇数时s2不能超过s1+1
规律二:通过变化,可以向两个1之间插任意个0
证明:1.有偶数个1在数列中时,可以把首位的1放到尾部去。所以对于偶数个1在数列中的数列可以随意地向两个1之间插数。
2.有奇数个1在数列中时,在尾部添1,又变成了情况1,然后达到目标后再把多添的1在首位删去。
因为当A串中1的个数为偶数时,可以在A串尾部添加任意个0。当A串中1的个数为奇数时,可以在尾部添加1个1。(因为添加完之后,1的个数就会变成偶数)所以我们可以将A串奇数个1的情况转成偶数个1的情况(通过在尾部加1),而偶数个1的情况,我们则可以将头部的1移动到尾部,并且可以在相邻两个1之间放任意个0(先在尾部补0,再删去头部的1,并在尾部加1)。所以可以将通过转换得到所有的情况。
设A串和B串的1的个数分别为s1,s2。
若s1为奇数,那么s1+1>=s2则可行。
若s1为偶数,那么s1>=s2则可行。
#include<cstdio>
#include<cstring>
using namespace std;
#define LOCAL
int A,B;
char s[1100];
int count()
{
int Lenth=strlen(s),q=0;
for(int i=0;i<=Lenth;i++) if(s[i]=='1') q++;
return q;
}
int main()
{
#ifdef LOCAL
freopen("A.in","r",stdin);
#endif
int T; scanf("%d",&T);
for(int i=1;i<=T;i++)
{
scanf("%s",s);
A=count();
scanf("%s",s);
B=count();
if(A&1) printf("%s\n",A+1>=B?"YES":"NO");
else printf("%s\n",A>=B?"YES":"NO");
}
#ifdef LOCAL
while(1);
#endif
return 0;
}