其他分享
首页 > 其他分享> > 2020牛客暑期多校训练营(第三场)Points Construction Problem

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

作者:互联网

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

题解:

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

image-20200721201915364

如上图,知道这个点了就可以自己思考了,注意图二其实就是这个图形的宽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\n");
            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\n",x);
        if (x == -1) printf("No\n");
        else {
            printf("Yes\n");
            int xx = -1, yy = 1;
            for (int i = 1; i <= x; i++) {
                printf("%d %d\n", xx, yy);
                xx--, yy++;
            }
            int res = n - x - (a + b - 1);
            for (int i = 1; i <= a; i++) printf("%d 1\n", i);
            for (int i = 2; i <= b; i++) printf("1 %d\n", i);
            int sx = 2, sy = 2;
            while (sx <= a && res) {
                printf("%d %d\n", sx, sy);
                sy++, res--;
                if (sy > b) {
                    sy = 2;
                    sx++;
                }
            }
        }
    }
}


标签:这个,多边形,int,sum,多校,牛客,printf,第三场
来源: https://www.cnblogs.com/EchoZQN/p/13357209.html