2020牛客暑期多校训练营(第三场)Points Construction Problem

2020牛客暑期多校训练营(第三场)Points Construction Problem

题解:

这个如果要知道每一个点涂成黑色,那么黑白点对的数量就是这个点的周长,那么这个题目就很简单了。

如上图,知道这个点了就可以自己思考了,注意图二其实就是这个图形的宽3加上这个高3乘以2,这个多边形求边长应该很简单吧。

后面有点像小学数学,首先枚举单独的点,也就是一个点的贡献是4的数量,假设 (x) ,那么假设合在一起的那个多边形的最长的宽是 (a) ,最长的高是 (b) ,那么多边形的贡献就是 ((a+b)*2)

所以总的贡献就是 : (sum=4*x+(a+b)*2)

这个多变形的点的数量是一个区间,([a+b-1,a*b])

所以最后有解就要满足: (sum=m \,\, and \,\, a+b-1<=n-x<=a*b)

枚举这个 (x) 即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
typedef long long ll;

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, m, x = -1;
        scanf("%d%d", &n, &m);
        if (m & 1) {
            printf("No
");
            continue;
        }
        int a = 0, b = 0;
        for (int i = 0; i <= n; i++) {
            int res = m / 2 - 2 * i;
            if (res < 0) break;
            if (res == 1) continue;
            a = res / 2, b = res - a;
            if (n - i <= a * b && n - i >= a + b - 1) {
                x = i;
                break;
            }
        }
//        printf("x=%d
",x);
        if (x == -1) printf("No
");
        else {
            printf("Yes
");
            int xx = -1, yy = 1;
            for (int i = 1; i <= x; i++) {
                printf("%d %d
", xx, yy);
                xx--, yy++;
            }
            int res = n - x - (a + b - 1);
            for (int i = 1; i <= a; i++) printf("%d 1
", i);
            for (int i = 2; i <= b; i++) printf("1 %d
", i);
            int sx = 2, sy = 2;
            while (sx <= a && res) {
                printf("%d %d
", sx, sy);
                sy++, res--;
                if (sy > b) {
                    sy = 2;
                    sx++;
                }
            }
        }
    }
}


原文地址:https://www.cnblogs.com/EchoZQN/p/13357209.html