题解 洛谷P2765 网络流24题.02【魔术球问题】
\(\huge\mathbb{DESCRIPTION}\)
编号:洛谷\(P2765\)、\(LOJ6003\)(与洛谷上本题输出格式有不同)
算法:网络最大流\(\mathbb{OR}\)贪心
来源:网络流\(24\)题
\(\huge\mathbb{SOLUTION}\)
这道题目我们可以用网络最大流来解决。
但是,我觉得贪心也可以啊。
事实证明,贪心是对的。
那么我们先来考虑一下怎么贪心。
不难想到一个贪心:放一个球在已经有的柱子上,比再开一个新柱子更优化。
那么考虑如何证明这个贪心的正确性。
设现在已经放好了\(A_1,A_2,A_3,A_4,\ldots,A_i,\ldots,A_j,\ldots,A_k,\ldots\)
设现在我要开始放\(A_x\)了。
那么我现在有两中策略:
- 在一个可以和\(A_x\)组成完全平方数的数\(A_i\)上面放。即:\(A_1,A_2,A_3,A_4,\ldots,A_x,\ldots,A_j,\ldots,A_k,\ldots\)
- 新开一个柱子。即:\(A_1,A_2,A_3,A_4,\ldots,A_i,\ldots,A_j,\ldots,A_k,\ldots,A_x\)
为了比较,我们再继续往后考虑\(A_{x+1}\)。
设\(A_i\)和\(A_x\)的和等于\(a^2\)。
易证,\(A_i+1\)不能放在\(A_i\)上面。
考虑到这一点,后面就迎刃而解了。
也可以感性理解一下啦\(\ldots\)
插播广告
读者:万恶的作者!
作者:懒得证了\(\ldots\)
回归正题
所以我们的贪心是正确的。
\(\huge\mathbb{CODE}\)
#include<bits/stdc++.h>
using namespace std;
int N;
int Ans;
int Count;
int Square[4001];
vector<int>Column[56];
int main(void)
{
register int i,j;
cin>>N;
for(i=1;i<=55;i++)
{
Square[i*i]=true;
}
while(true)
{
for(i=1;i<=Count;i++)
{
if(Square[Column[i][Column[i].size()-1]+Ans])
{
Column[i].push_back(Ans);
i=0;
Ans++;
continue;
}
}
if(Count<N)
{
Count++;
Column[Count].push_back(Ans);
Ans++;
}
else
{
break;
}
}
Ans--;
cout<<Ans<<endl;
for(i=1;i<=N;i++)
{
for(j=0;j<Column[i].size();j++)
{
if(!Column[i][j])
{
continue;
}
cout<<Column[i][j]<<' ';
}
cout<<endl;
}
return 0;
}
不要妄图追上西坠的太阳,而是要在黎明前就等着它!