点击打开链接
题目意思很简单啦,给定三个数,n,m,k,其中n,m为边长,求以n,m为边的矩形中有多少个周长不超过k的矩形.
首先需要说明的是,当k>=2*(n+m)时,明显没啥意思,题中矩形周长最大才200000,样例给了个1e9,明显是卖萌的(嘻嘻)。
还有就是,看这题的时候,有人说了句组合数学,结果误导了帕斯喵()。例如在5个数中取两个相邻的数可不是c(5,2)哦,是5-2+1。
回到题目上:
样例 2 2 6
小矩形一边为i,一边为j,当i=1时,这时候有2-1+1种选法,j可以取1和2,当j=1时,有
2-1+1种选法,当j=2时,有2-2+1种选法,
再然后,i=2时,j只能1了。
这样我们咧,可以得到这三个等式:
4=(2-1+1)*(2-1+1)
2=(2-1+1)*(2-2+1)
2=(2-2+1)*(2-1+1)
加起来就是8了。
我们再抽象一下这几个等式,得到:
(n-i+1)(m-j+1)其中j<=k/2-i;
大家可能会说这有两个变量,不能求和,这与多元函数求导一样,我们先固定一个变量,这里,先固定i,求和得到(n-i+1){(m+1)*(k/2-i)+[1+(k/2-i)]/2 *(k/2-i)},(大家最好,还是自己在草稿纸上推导一下)
然后我们再对这个式子累加就行了,一个for循环就OK了。
代码:
#include <iostream>
using namespace std;
int main()
{
long long n,m,k,res,tmp;//res用来存周长的一半;
long long ans;
while(cin>>n>>m>>k)
{
res=k/2;
ans=0;
for(int i=1;i<=min(res-1,n);i++)
{
tmp=min((res-i),m);
ans=ans+(n-i+1)*((m+1)*tmp-(1+tmp)*tmp/2);
}
cout<<ans<<endl;
}
return 0;
}
还有就是要说明一下,int*int可能会爆int哦,所以呢,要定义为long long