题目链接:http://codeforces.com/contest/599/problem/D
题意:对于一个n*m的矩形,其 “方块值” 为它能容纳下单个方块的方法数。现给你一个x,让你求出所有方块值为x的矩形,按n递增顺序输出。
样例如下:
解法:推导公式即可,对于边长n*m(n<=m),其能容纳边长为k的方块的不同方法数为(n-k)*(m-k);
则其方块值x=sigma(n-k)*(m-k) (0<=k<=n-1);
然后化简 x=(3*n*n*m-n*n*n+3*n*m+n)/ 6
m每增加1,x增加(n*n+n)/ 2;
然后枚举n,再排序输出即可。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long LL;
struct point{
LL x,y;
point(){}
point(LL _x,LL _y){
x=_x; y=_y;
}
};
bool cmp(point a,point b){
return a.x<b.x||( a.x==b.x && a.y<b.y );
}
LL cal(LL n,LL m){
return (3*n*n*m-n*n*n+3*n*m+n)/6;
}
vector<point> ans;
int main (){
LL x;
while(cin>>x){
LL cur=1;
ans.clear();
while(cal(cur,cur)<=x){
LL rest = x-cal(cur,cur);
if(rest%((cur*cur+cur)/2)==0){
ans.push_back(point(cur,(cur+rest/((cur*cur+cur)/2))));
if(rest!=0)
ans.push_back(point((cur+rest/((cur*cur+cur)/2)),cur));
}
cur++;
}
sort(ans.begin(),ans.end(),cmp);
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++)
cout<<ans[i].x<<" "<<ans[i].y<<endl;
}
return 0;
}