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;
}
posted @ 2021-02-07 17:18  violet_holmes  阅读(62)  评论(0编辑  收藏  举报