Rectangle
frog has a piece of paper divided into nn rows and mm columns. Today, she would like to draw a rectangle whose perimeter is not greater than kk.
Find the number of ways of drawing.
Input
The input consists of multiple tests. For each test:
The first line contains 33 integer n,m,k(1<=n,m<=5*1e4,0<=k<=1e9)
Output
For each test, write 11 integer which denotes the number of ways of drawing.
Sample Input
2 2 6
1 1 0
50000 50000 1000000000
Sample Output
8
0
1562562500625000000
题意:n*m的矩形能够画出多少种周长不超过K的矩形
从图中可以看出由(n-i+1)个长度为i的边与(m-j+1)个长度为j的边组成了(n-i+1)*(m-j+1)个i*j的矩阵。
又要求周长不超过k,i,j需要满足以下关系式
1<=i<=(k/2)-1
1<=j<=(k/2)-i
两重循环可以求解
但是k的范围为(0<=k<=1e9)
时间复杂度为(o2)会超时。
想办法把两重循环变成一重循环
发现长度为i的边对应的长度为j的边的个数是一个等差数列的前(K/2-1)的和。
例如i=1时对应边长为j(1<=j<=k/2-1)的矩形的数量分别为
(m-(1)+1) , (m-(2)+1) , ... ,(m-(k/2-2)+1) , (m-(k/2-1)+1)
则i=1的周长不超k的矩形有
(m+m-(k/2-1)+1)*(k/2-1)/2个
AC代码:
#include <cstdio>
using namespace std;
typedef long long ll;
ll N,M,K;
int main(){
while(~scanf("%lld%lld%lld",&N,&M,&K)){
K=K/2;
ll sum=0;
for(ll i=1;i<=N && i<K;i++){
ll x,y;
ll temp=(K-i)<M?(K-i):M;//显然j的范围不能超过M
ll sumi=(N-i+1);
ll sumj=(M+M-temp+1)*(temp)/2;
sum+=sumi*sumj;
//sum=sum+(M+M-(K-i)+1)*(K-i)/2;
}
printf("%lld\n",sum);
}
return 0;
}