题解:P13938 [EC Final 2019] City

· · 题解

分别计算与已有线条重叠的(就是横的和竖的)和斜的线段的个数,并相加。

对于与已有线条重叠的线段

要使中点在已有线的交点上,就要让边长是偶数,就是让两个端点坐标的的奇偶性相同。

如果再去枚举端点的话,时间复杂度 O(n^4),会超时。

所以要直接算出端点数量,分别计算在上下方向能延伸的最大长度的最小值,和左右方向能延伸的最大长度的最小值。把这两个值相乘。

代码

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    n++;
    m++;
    int n1=n/2,m1=m/2;
    int n2=n-n1,m2=m-m1;
    long long sum=n1*(n1-1)/2*m+n2*(n2-1)/2*m+m1*(m1-1)/2*n+m2*(m2-1)/2*n;//横竖的数量
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            sum+=min((n-i)*(m-j),(i-1)*(j-1))*2;
        }
    }
    cout<<sum;
}