E. Rectangle
Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format:
%lld Java class name:
Main
frog has a piece of paper divided into \(n\) rows and \(m\) columns. Today, she would like to draw a rectangle whose perimeter is not greater than \(k\).
There are \(8\) (out of \(9\)) ways when \(n = m = 2, k = 6\)
Find the number of ways of drawing.
Input
The input consists of multiple tests. For each test:
The first line contains \(3\) integer \(n, m, k\) (\(1 \leq n, m \leq 5 \cdot 10^4, 0 \leq k \leq 10^9\)).
Output
For each test, write \(1\) 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
超时的算法
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k))
{
k/=2;
long long sum=0;
for(int i=1;;i++)
{
if(i>=k||i>n)
break;
for(int j=1;;j++)
{
if(j>=k||j>m||j+i>k)
break;
sum+=(n-i+1)*(m-j+1);
}
}
printf("%lld\n",sum);
}
}
根据等差公式优化成O(n)的时间复杂度
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
long long int n,m,k;
while(~scanf("%lld%lld%lld",&n,&m,&k))
{
k/=2;
long long sum=0;
if(k>n+m)
k=n+m;
for(long long i=1;;i++)
{
if(i>=k||i>n)
break;
if(k-i>=m)
{sum+=(((m+1)*m/2)*(n-i+1)); //等差公式 ,从m+....+1
}
else
{sum+=(((2*m-k+i+1)*(k-i)/2)*(n-i+1)); //等差公式,从m+..+(m-(k-i)+1)<span id="transmark"></span>
}
}
printf("%lld\n",sum);
}
}