CF599D Solution
题解
可以发现,一个\(n\times m(m\ge n)\)的矩形所包含的正方形数\(x=\sum\limits_{i=1}^ni\cdot (m-(n-i+1)+1)\)(纵向可以放\(i\)个的方形边长为\((n-i+1)\),横向可以放\(m-(n-i+1)+1\)个),进一步推导得\(x=\sum\limits_{i=1}^n(i^2+i\cdot ( m-n))=\sum\limits_{i=1}^ni^2+\sum\limits_{i=1}^ni\cdot (m-n)\)。可以枚举\(n\),通过维护2个前缀变量\(sum=\sum\limits_{i=1}^n i,sq=\sum\limits_{i=1}^ni^2\)解出\(m\)即可。当\(sq>k\)时\(m-n<0\),退出循环。因为题目要求输出方案,时间一定可以通过(机房神仙比对函数图像后得出时间复杂度约为\(O(\sqrt[2.5]x)\)。
AC代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
vector<pair<int,int> > ans;//不知道数组大小因此使用vector(数组1e7应该能过(´▽`) )
signed main()
{
int sq=0,sum=0,k;
scanf("%lld",&k);
for(int i=1;;i++)
{
sq+=i*i; sum+=i;
if(sq>k) break;
if((k-sq)%sum==0) ans.push_back(make_pair(i,i+(k-sq)/sum));
}
int siz=ans.size();
if(ans[siz-1].first==ans[siz-1].second) printf("%lld\n",siz*2-1);
else printf("%lld\n",siz*2);
for(int i=0;i<siz;i++) printf("%lld %lld\n",ans[i].first,ans[i].second);
if(ans[siz-1].first==ans[siz-1].second) siz--;
for(int i=siz-1;i>=0;i--) printf("%lld %lld\n",ans[i].second,ans[i].first);
return 0;
}