2部マッチングするだけ。
入力の仕様に殺意を覚えた。1時間も悩んだ。
const int N = 500 + 10;
vector<int> g[N];
int match[N];
bool vis[N];
void add_edge(int src, int dst)
{
dst += (N / 2);
g[src].push_back(dst);
g[dst].push_back(src);
return ;
}
bool rec(int v)
{
vis[v] = true;
for (int i = 0; i < g[v].size(); ++i) {
int u = g[v][i];
int w = match[u];
if (w < 0 || (!vis[w] && rec(w))) {
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
int matching(void)
{
fill(match, match + N, -1);
int ret = 0;
for (int i = 0; i < N; ++i) {
if (match[i] == -1) {
fill(vis, vis + N, false);
if (rec(i)) ++ret;
}
}
return ret;
}
int gcd(int a, int b)
{
if (a < b) swap(a, b);
if (a % b == 0) return b;
else return gcd(b, a % b);
}
bool valid(lli a, lli b)
{
if (gcd(a, b) != 1) return false;
lli x = a * a + b * b;
lli c = (lli)ceil(sqrt((double)x));
lli d = (lli)floor(sqrt((double)x));
return (c * c == x) && (d * d == x);
}
class PythTriplets {
public:
int findMax(vector <string> stick)
{
fill(g, g + N, vector<int>());
vector<int> ls;
istringstream iss(accumulate(stick.begin(), stick.end(), string("")).c_str());
for (int n; iss >> n; ls.push_back(n)) ;
sort(ls.begin(), ls.end());
for (int i = 0; i < ls.size(); ++i) {
for (int j = 0; j < ls.size(); ++j) {
if (valid(ls[i], ls[j])) add_edge(i, j);
}
}
return matching() / 2;
}
};