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\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