typedef complex<double> CMP;
class CheckerFreeness { public:
string isFree(vector <string> whiteX, vector <string> whiteY, vector <string> blackX, vector <string> blackY)
{
stringstream swx(accumulate(whiteX.begin(), whiteX.end(), string("")));
stringstream swy(accumulate(whiteY.begin(), whiteY.end(), string("")));
stringstream sbx(accumulate(blackX.begin(), blackX.end(), string("")));
stringstream sby(accumulate(blackY.begin(), blackY.end(), string("")));
vector<CMP> w;
for(int x,y; (swx>>x)&&(swy>>y); )
w.push_back(CMP(x,y));
vector<CMP> b;
for(int x,y; (sbx>>x)&&(sby>>y); )
b.push_back(CMP(x,y));
return has_checker(w,b) ? "NO" : "YES";
}
bool has_checker(const vector<CMP>& w, const vector<CMP>& b)
{
for(int i=0; i<w.size(); ++i)
for(int k=i+1; k<w.size(); ++k)
if(has_crosser(w[i], w[k], b))
return true;
return false;
}
bool has_crosser(CMP a, CMP b, const vector<CMP>& ps)
{
vector<double> arg_a, arg_b;
vector<CMP> qs;
for(int i=0; i<ps.size(); ++i)
{
double d = arg( (ps[i]-a)/(b-a) );
if(d > 0) {
arg_a.push_back(d);
d = arg( (ps[i]-b)/(b-a) );
arg_b.push_back(d);
} else {
qs.push_back(ps[i]);
}
}
sort(arg_a.begin(), arg_a.end());
sort(arg_b.begin(), arg_b.end());
for(int i=0; i<qs.size(); ++i)
{
CMP q = qs[i];
double aMax = arg((a-q) / (b-a));
double bMax = arg((b-q) / (b-a));
int aNum = lower_bound(arg_a.begin(), arg_a.end(), aMax) - arg_a.begin();
int bNum = lower_bound(arg_b.begin(), arg_b.end(), bMax) - arg_b.begin();
if(aNum != bNum)
return true;
}
return false;
}
};
dHlwZWRlZiBjb21wbGV4PGRvdWJsZT4gQ01QOwoKY2xhc3MgQ2hlY2tlckZyZWVuZXNzIHsgcHVibGljOgogICAgc3RyaW5nIGlzRnJlZSh2ZWN0b3IgPHN0cmluZz4gd2hpdGVYLCB2ZWN0b3IgPHN0cmluZz4gd2hpdGVZLCB2ZWN0b3IgPHN0cmluZz4gYmxhY2tYLCB2ZWN0b3IgPHN0cmluZz4gYmxhY2tZKQoJewoJCXN0cmluZ3N0cmVhbSBzd3goYWNjdW11bGF0ZSh3aGl0ZVguYmVnaW4oKSwgd2hpdGVYLmVuZCgpLCBzdHJpbmcoIiIpKSk7CgkJc3RyaW5nc3RyZWFtIHN3eShhY2N1bXVsYXRlKHdoaXRlWS5iZWdpbigpLCB3aGl0ZVkuZW5kKCksIHN0cmluZygiIikpKTsKCQlzdHJpbmdzdHJlYW0gc2J4KGFjY3VtdWxhdGUoYmxhY2tYLmJlZ2luKCksIGJsYWNrWC5lbmQoKSwgc3RyaW5nKCIiKSkpOwoJCXN0cmluZ3N0cmVhbSBzYnkoYWNjdW11bGF0ZShibGFja1kuYmVnaW4oKSwgYmxhY2tZLmVuZCgpLCBzdHJpbmcoIiIpKSk7CgoJCXZlY3RvcjxDTVA+IHc7CgkJZm9yKGludCB4LHk7IChzd3g+PngpJiYoc3d5Pj55KTsgKQoJCQl3LnB1c2hfYmFjayhDTVAoeCx5KSk7CgoJCXZlY3RvcjxDTVA+IGI7CgkJZm9yKGludCB4LHk7IChzYng+PngpJiYoc2J5Pj55KTsgKQoJCQliLnB1c2hfYmFjayhDTVAoeCx5KSk7CgoJCXJldHVybiBoYXNfY2hlY2tlcih3LGIpID8gIk5PIiA6ICJZRVMiOwoJfQoKCWJvb2wgaGFzX2NoZWNrZXIoY29uc3QgdmVjdG9yPENNUD4mIHcsIGNvbnN0IHZlY3RvcjxDTVA+JiBiKQoJewoJCWZvcihpbnQgaT0wOyBpPHcuc2l6ZSgpOyArK2kpCgkJZm9yKGludCBrPWkrMTsgazx3LnNpemUoKTsgKytrKQoJCQlpZihoYXNfY3Jvc3Nlcih3W2ldLCB3W2tdLCBiKSkKCQkJCXJldHVybiB0cnVlOwoJCXJldHVybiBmYWxzZTsKCX0KCglib29sIGhhc19jcm9zc2VyKENNUCBhLCBDTVAgYiwgY29uc3QgdmVjdG9yPENNUD4mIHBzKQoJewoJCXZlY3Rvcjxkb3VibGU+IGFyZ19hLCBhcmdfYjsKCQl2ZWN0b3I8Q01QPiBxczsKCQlmb3IoaW50IGk9MDsgaTxwcy5zaXplKCk7ICsraSkKCQl7CgkJCWRvdWJsZSBkID0gYXJnKCAocHNbaV0tYSkvKGItYSkgKTsKCQkJaWYoZCA+IDApIHsKCQkJCWFyZ19hLnB1c2hfYmFjayhkKTsKCQkJCWQgPSBhcmcoIChwc1tpXS1iKS8oYi1hKSApOwoJCQkJYXJnX2IucHVzaF9iYWNrKGQpOwoJCQl9IGVsc2UgewoJCQkJcXMucHVzaF9iYWNrKHBzW2ldKTsKCQkJfQoJCX0KCQlzb3J0KGFyZ19hLmJlZ2luKCksIGFyZ19hLmVuZCgpKTsKCQlzb3J0KGFyZ19iLmJlZ2luKCksIGFyZ19iLmVuZCgpKTsKCQlmb3IoaW50IGk9MDsgaTxxcy5zaXplKCk7ICsraSkKCQl7CgkJCUNNUCBxID0gcXNbaV07CgkJCWRvdWJsZSBhTWF4ID0gYXJnKChhLXEpIC8gKGItYSkpOwoJCQlkb3VibGUgYk1heCA9IGFyZygoYi1xKSAvIChiLWEpKTsKCQkJaW50IGFOdW0gPSBsb3dlcl9ib3VuZChhcmdfYS5iZWdpbigpLCBhcmdfYS5lbmQoKSwgYU1heCkgLSBhcmdfYS5iZWdpbigpOwoJCQlpbnQgYk51bSA9IGxvd2VyX2JvdW5kKGFyZ19iLmJlZ2luKCksIGFyZ19iLmVuZCgpLCBiTWF4KSAtIGFyZ19iLmJlZ2luKCk7CgkJCWlmKGFOdW0gIT0gYk51bSkKCQkJCXJldHVybiB0cnVlOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9Cn07Cg==