我是直接用贪心跑的,但其实可以用网络流来跑。
对于网络流,通过分析可以得到,如果将i+j为完全平方数的i与j连上边。
那么每一根柱子就是一条路径,答案就是有n条路径的最小路径覆盖。
可以自己画图YY。
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
const int N=65;
int n;
vector<int> v[N];
inline bool pd(int x)
{
int root=floor(sqrt(x));
return root*root==x;
}
int main()
{
scanf("%d",&n);
int x=1;
for (int k=1; k<=n; k++)
{
while (1)
{
bool flag=false;
for (int i=0; i<k; i++)
{
if (v[i].empty()||pd(v[i].back() + x))
{
v[i].push_back(x++);
flag=true;
break;
}
}
if (!flag) break;
}
}
printf("%d\n",x-1);
for (int i=0; i<n; i++)
{
for (size_t j=0; j<v[i].size(); j++)
printf("%d%c", v[i][j], j==v[i].size()-1?'\n':' ');
}
return 0;
}