链接:http://codeforces.com/problemset/problem/215/C
给你n*m矩阵,问有多少个不同的 (a, b, c, d, x0, y0) 面积等于s。
- |x0 - x| ≤ a and |y0 - y| ≤ b
- |x0 - x| ≤ c and |y0 - y| ≤ d
满足这个条件 相当于两个一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 ",ans); scanf("%d%d%d",&n,&m,&s); return 0; }