标签:
链接:http://codeforces.com/problemset/problem/215/C
给你n*m矩阵,问有多少个不同的 (a,?b,?c,?d,?x0,?y0) 面积等于s。
满足这个条件 相当于两个一x0 ,y0 为中心的,边长全为奇数的矩形并。
一个矩形长为2a+1,宽为2b+1 另一个是(2*c+1) * (2*d+1)
做法:
枚举其中一个矩形的长和宽。
如果面积超过s显然不行。
如果等于s,那么另一个肯定比它小或者相等。
ans+=(n-i/2*2)*(m-j/2*2)* (((i/2+1)*(j/2+1)-1)*2+1);
(n-i/2*2)*(m-j/2*2) 这个算有多少位子 可以做为矩形 中心
(((i/2+1)*(j/2+1)-1)*2+1) 枚举那个小的边长
如果小于s的话,枚举另一个矩阵的长度,长度小于i
然后计算宽度。
宽度如果小于m并且也是奇数
ans+=(n-i/2*2)*(m-wid/2*2)*2; 枚举中心点可以在的位置,因为两个矩形不同所以abcd可以对换 所以*2
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <map> int main() { int n,m,s; scanf("%d%d%d",&n,&m,&s); __int64 ans=0; for(int i=1;i<=n;i+=2)//枚举比较长的长方形 长度 { for(int j=1;j<=m;j+=2) { if(i*j>s) continue; else if(i*j==s)//一个包含另一个 { ans+=(n-i/2*2)*(m-j/2*2)* (((i/2+1)*(j/2+1)-1)*2+1); // 位子*枚举边长 } else { for(int len=1;len<i;len+=2)//长小的 { if((s-i*j)%len==0) { int wid=(s-i*j)/(len)+j; //长的 j //宽的 wid if(wid<=m&&(wid&1)) ans+=(n-i/2*2)*(m-wid/2*2)*2; //确定位置 因为不同 所以abcd可以换 *2 } } } } } printf("%I64d\n",ans); scanf("%d%d%d",&n,&m,&s); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013532224/article/details/46883987