Codeforces 599D Spongebob and Squares
题意
给出x,求全部长n宽m的正方形网格图,里面有x个正方形.
题解
首先推长
n
n
宽的网格图的正方形个数的公式.
不妨假设n≤m.对于边长i=1→n的正方形来说,每一种都有(n−i+1)(m−i+1)个.nm+(n−1)(m−1)+(n−2)(m−2)+(n−3)(m−3)+…+(n−n+1)(m−n+1)=xnm+nm−n−m+1+nm−2n−2m+4+nm−3n−3m+9+…+nm−(n−1)n−(n−1)m+(n−1)(n−1)n2m−(1+2+3+4+5+…+(n−1))(n+m)+(1+4+9+…+(n−1)2)=xn2m−n(n−1)(n+m)2+(n−1)n(2∗n−1)6=x化简得n(n+1)(3m−n+1)6=x,n(n+1)(3m−n+1)=x∗6;m=(x∗6/(n2+n)+n−1)/3
不
妨
假
设
n
≤
m
.
对
于
边
长
i
=
1
→
n
的
正
方
形
来
说
,
每
一
种
都
有
(
n
−
i
+
1
)
(
m
−
i
+
1
)
个
.
n
m
+
(
n
−
1
)
(
m
−
1
)
+
(
n
−
2
)
(
m
−
2
)
+
(
n
−
3
)
(
m
−
3
)
+
…
+
(
n
−
n
+
1
)
(
m
−
n
+
1
)
=
x
n
m
+
n
m
−
n
−
m
+
1
+
n
m
−
2
n
−
2
m
+
4
+
n
m
−
3
n
−
3
m
+
9
+
…
+
n
m
−
(
n
−
1
)
n
−
(
n
−
1
)
m
+
(
n
−
1
)
(
n
−
1
)
n
2
m
−
(
1
+
2
+
3
+
4
+
5
+
…
+
(
n
−
1
)
)
(
n
+
m
)
+
(
1
+
4
+
9
+
…
+
(
n
−
1
)
2
)
=
x
n
2
m
−
n
(
n
−
1
)
(
n
+
m
)
2
+
(
n
−
1
)
n
(
2
∗
n
−
1
)
6
=
x
化
简
得
n
(
n
+
1
)
(
3
m
−
n
+
1
)
6
=
x
,
n
(
n
+
1
)
(
3
m
−
n
+
1
)
=
x
∗
6
;
m
=
(
x
∗
6
/
(
n
2
+
n
)
+
n
−
1
)
/
3
好.然后我们在
n≤m
n
≤
m
的情况下枚举
n
n
,判断是否存在符合要求的即可.
但是朴素的枚举会T,我们要考虑枚举上界.
因为
x≤1018
x
≤
10
18
,故此我们找出
n=m
n
=
m
的时候正方形数目大于
1018
10
18
的最小数字.
大略是
1.5×106
1.5
×
10
6
.这就是枚举上界.
那么这题就结束了.
#include<bits/stdc++.h> //Ithea Myse Valgulious
namespace chtholly{
typedef long long ll;
#define re0 register int
#define rec register char
#define rel register ll
#define gc getchar
#define pc putchar
#define p32 pc(' ')
#define pl puts("")
/*By Citrus*/
inline int read(){
int x=0,f=1;char c=gc();
for (;!isdigit(c);c=gc()) f^=c=='-';
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return f?x:-x;
}
template <typename mitsuha>
inline bool read(mitsuha &x){
x=0;int f=1;char c=gc();
for (;!isdigit(c)&&~c;c=gc()) f^=c=='-';
if (!~c) return 0;
for (;isdigit(c);c=gc()) x=(x<<3)+(x<<1)+(c^'0');
return x=f?x:-x,1;
}
template <typename mitsuha>
inline int write(mitsuha x){
if (!x) return 0&pc(48);
if (x<0) x=-x,pc('-');
int bit[20],i,p=0;
for (;x;x/=10) bit[++p]=x%10;
for (i=p;i;--i) pc(bit[i]+48);
return 0;
}
inline char fuhao(){
char c=gc();
for (;isspace(c);c=gc());
return c;
}
}using namespace chtholly;
using namespace std;
typedef pair<ll,ll> pll;
vector<pll> ans;
int main(){
ll x,n;read(x),x*=6;
for (n=1;n<=2e6;++n){
if (x%(n*n+n)) continue;
ll t=x/(n*n+n)+n-1;
if (t%3) continue;
ll m=t/3;
if (n>m) break;
ans.push_back(pll(n,m));
}
int i,len=ans.size();
for (i=0;i<len;++i){
if (ans[i].second==ans[i].first) continue;
ans.push_back(pll(ans[i].second,ans[i].first));
}
cout<<ans.size()<<endl;
sort(ans.begin(),ans.end());
for (auto llx:ans) printf("%lld %lld\n",llx.first,llx.second);
}
谢谢大家.