/*
1<x<y<80
把x+y告诉甲,x*y告诉乙
甲对乙说:“我不知道这两个数,不过你也不知道”
乙说:“我现在知道了”
甲说:“我现在也知道了”
*/
#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
class foo;
typedef vector< foo > foo_set;
typedef vector< foo >::iterator foo_iterator;
class foo
{
public:
foo(int _x, int _y)
{
x = _x;
y = _y;
sum = x+y;
acc = x*y;
}
foo_set get_sum_similar() const;
foo_set get_acc_similar() const;
bool has_multi_factor_pair() const;
int x;
int y;
int sum;
int acc;
};
inline ostream& operator<<(ostream& target, const foo& f)
{
target << f.x << "/t" << f.y << "/t" << f.sum << "/t" << f.acc;
return target;
}
struct if_remove1
{
bool operator()(const foo& f);
};
struct if_remove2
{
bool operator()(const foo& f);
};
struct if_remove3
{
bool operator()(const foo& f);
};
int main()
{
foo_set result;
for (int x = 2; x < 80; ++x)
{
for (int y = x+1; y < 80; ++y)
{
result.push_back(foo(x, y));
}
}
/*
甲猜乙不知道,则,甲的相同和集合中元素可多重分解
*/
result.erase(remove_if(result.begin(), result.end(), if_remove1()), result.end());
/*
乙知道,则,乙的相等积集合中元素有且仅有一个满足上述“甲的观点”
*/
result.erase(remove_if(result.begin(), result.end(), if_remove2()), result.end());
/*
甲知道,则,甲的相等和集合中元素有且仅有一个满足上述“乙的观点”
*/
result.erase(remove_if(result.begin(), result.end(), if_remove3()), result.end());
copy(result.begin(), result.end(), ostream_iterator< foo >(cout, "/n"));
return 0;
}
foo_set foo::get_sum_similar() const
{
foo_set fs;
for (int i = 2; i < sum/2; ++i)
{
fs.push_back(foo(i, sum-i));
}
return fs;
}
foo_set foo::get_acc_similar() const
{
foo_set fs;
for (int i = 2; i < ::sqrt(acc); ++i)
{
if (acc % i == 0 && acc/i < 80)
{
fs.push_back(foo(i, acc/i));
}
}
return fs;
}
bool foo::has_multi_factor_pair() const
{
int times = 0;
for (int _x = 2; _x < ::sqrt(acc); ++_x)
{
if (acc % _x == 0)
{
++times;
}
if (times > 1)
{
return true;
}
}
return false;
}
bool if_remove1::operator()(const foo& f)
{
foo_set fs = f.get_sum_similar();
for (foo_iterator it = fs.begin(); it != fs.end(); ++it)
{
if (!it->has_multi_factor_pair())
{
return true;
}
}
return false;
}
bool if_remove2::operator()(const foo& f)
{
int times = 0;
foo_set fs = f.get_acc_similar();
for (foo_iterator it = fs.begin(); it != fs.end(); ++it)
{
if (!if_remove1()(*it))
{
++times;
}
if (times > 1)
{
return true;
}
}
if (times == 1)
{
return false;
}
return true;
}
bool if_remove3::operator()(const foo& f)
{
int times = 0;
foo_set fs = f.get_sum_similar();
for (foo_iterator it = fs.begin(); it != fs.end(); ++it)
{
if (!if_remove2()(*it))
{
++times;
}
if (times > 1)
{
return true;
}
}
if (times == 1)
{
return false;
}
return true;
}