Codeforces #180 div2 C Parity Game

// Codeforces #180 div2 C Parity Game
//
// 这道题的题目意思就不解释了
//
// 题目有那么一点难(对于我而言),不多说啦
//
// 解题思路:
//
// 首先如果a串和b串相等,不多说直接YES
// 如果b串全是0,直接YES
// 注意到a串有一个性质,1的个数不会超过本身的加1.
// a有个1的上限设为x,b有个1的个数设为y,则如果x < y
// 那么直接NO。
//
// 现在一般情况下,就是模拟啦,找到a的后缀和b的前缀一样的
// 最长的长度设为buf。之后对buf之后的部分进行扫描,如果
// b[i] == '1' ,则在a串的前suf中找一个1,把它添到后面,
// 这样就可以找到了。最后判一下在a中的j下标是否小于suf就可以了
// 
// 注意:如果开始a中1的个数是1的时候那么在第一次找到b[i]是1的
// 时候,不用找1.
//
// 解题:
//
// 这种字符串的题目,情况相对时有那么一点多,关键是以前看过前缀和后缀
// 作为状态进行转移的动态规划,所以相对有那么一点感觉,感觉是对了,但
// 经历的时间还是太长了,继续练吧。。。。

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#define ceil(a,b) (((a)+(b)-1)/(b))
#define endl '\n'
#define gcd __gcd
#define highBit(x) (1ULL<<(63-__builtin_clzll(x)))
#define popCount __builtin_popcountll
typedef long long ll;
using namespace std;
const int MOD = 1000000007;
const long double PI = acos(-1.L);

template<class T> inline T lcm(const T& a, const T& b) { return a/gcd(a, b)*b; }
template<class T> inline T lowBit(const T& x) { return x&-x; }
template<class T> inline T maximize(T& a, const T& b) { return a=a<b?b:a; }
template<class T> inline T minimize(T& a, const T& b) { return a=a<b?a:b; }

const int maxn = 1008;
string a;
int fa[maxn];
string b;
int fb[maxn];
int x,y;
int len1,len2;
int suf;
bool cmp(int u){
	for (int i=u;i<u+len2;i++){
		if (a[i]!=b[i])
			return false;
	}
	return true;
}

void solve(){
	string s;

	suf = -1;
	int i;
	for (i=len1-1;i>=0;i--){
		s = a.substr(i);
		if (s==b.substr(0,len1-i)){
			suf = i;	
			break;
		}
	}
	//cout << 
//	cout << a << endl;
//	cout << b << endl;
	//cout << "suf = " << suf << endl;
	int flag = 0;

	//cout << "fb = " << fb[len2-1] << endl;
	if (suf == -1)
		suf = len1-1;
	int x = len1 - suf;
	int j = 0;
	int even = 0;
	//cout << " x " << x << endl;
	i = x;
	if (fa[len1]&1){
		b[i] == '0';
		while(!a[j]&&j<suf)
			j++;
		j++;
	}
	for (; i < len2; i++) {
		if (b[i]=='1'){
			while(j<suf){
				if (s[j]=='1'){
					break;
				}
				j++;
			}
		}
	}
	if (j<suf){
		puts("YES");
	}else {
		puts("NO");
	}
}

void init(){
	memset(fa,0,sizeof(fa));
	memset(fb,0,sizeof(fb));
	len1 = a.size();
	len2 = b.size();
	x = 0;
	y = 0;
	int i;
	for (i=0;i<len1;i++){
		if (a[i]=='1'){
			x++;
			fa[i] = x;
		}
	}
	for (i=0;i<len2;i++)
		if (b[i]=='1'){
			y++;
			fb[i] = y;
		}
	if (( !(x&1) && x < y) || ((x&1) && x+1 < y)){
		puts("NO");
		return ;
	}

	if (!fb[len2-1]){
		puts("YES");
		return ;
	}

	solve();

}

int main() {
	//freopen("G:\\Code\\1.txt","r",stdin);
	while(cin >> a >> b){
		if (a==b){
			puts("YES");
			continue;
		}
		init();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值