SCU - 4440 2015年四川省程序ACM设计竞赛E题目

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.

There are 8 (out of 9) ways when n = m = 2, k = 6

There are 88 (out of 99) ways when n=m=2,k=6n=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 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*m的矩阵能够画出多少个i*j的矩阵?


从图中可以看出由(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;
}





猜你喜欢

转载自blog.csdn.net/Rainbow_storm/article/details/79856107