【JZOJ比赛】2019.11.5 JZOJ B组

3831 地图的密度

题意

点(x1,y1)与点(x2,y2)的距离为max(|x1-x2|,|y1-y2|),求出与每个点距离不超过r的点(i,j),f[i,j]的总和。

思路

可以发现规律,距离是按一圈一圈增加的,所以我们可以用二维前缀和维护答案。

代码

#include <cctype>
#include <cstdio>

int n, r;
int a[251][251], s[251][251];

inline int input() {
	char c = getchar();
	int res = 0;
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) res = (res << 3) + (res << 1) + c - 48, c = getchar();
	return res;
}

signed main() {
	freopen("map.in", "r", stdin);
	freopen("map.out", "w", stdout);
	n = input();
	r = input();
	for (register int i = 1; i <= n; i++)
		for (register int j = 1; j <= n; j++)
			a[i][j] = input();
	for (register int i = 1; i <= n; i++)
		for (register int j = 1; j <= n; j++)
			s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
	int x11, x22, y11, y22;
	for (register int i = 1; i <= n; i++, printf("\n"))
		for (register int j = 1; j <= n; j++) {
			x11 = i - r > 0 ? i - r : 1;
			y11 = j - r > 0 ? j - r : 1;
			x22 = i + r <= n ? i + r : n;
			y22 = j + r <= n ? j + r : n;
			printf("%d ", s[x22][y22] - s[x11 - 1][y22] - s[x22][y11 - 1] + s[x11 - 1][y11 - 1]);
		}

}

3832 在哪里建酿酒厂

题意

一个环形,确定一个点,使得这个点到其它点的权值最小。

思路

观察到n<=104n<=10^4,暴力卡卡可过。

代码

#include <cstdio>
#include <cctype>
#include <algorithm>

long long n, ans = 1000000000000000000ll;
long long z[10001], d[10001];

inline long long input() {
	char c = getchar();
	long long res = 0;
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) res = (res << 3) + (res << 1) + c - 48, c = getchar();
	return res;
}

int main() {
	scanf("%lld", &n);
	long long s = 0;
	for (register long long i = 1; i <= n; i++)
		z[i] = input(), d[i] = input(), s += d[i];
	for (register long long i = 1; i <= n; i++) {
		long long res = 0, dis = 0, x;
		for (long long j = i + 1; j <= n + i - 1; j++) {
			x = (j - 1) % n + 1;
			if (i == x) continue;
			dis += d[x - 1 == 0 ? n : x - 1];
			res += std::min(dis, s - dis) * z[x];
		}
		ans = std::min(ans, res);
	}
	printf("%lld", ans);
}

1956 矩形

做过原题,在判断矩形是否覆盖时要注意,我这里是判断:
上下左右四种情况矩形相离,或点在矩形的四个角上。


3833 平坦的折线

题意

给出几个点,徐要几条平坦的折线覆盖它们,平坦的折线定义为任何两个点之间连接的直线段与x轴的夹角在-45~45之间,求出最少需要的折线。

思路

把座标系转45度,可以发现当一个点在另一个点的右上角我们就可以用同一条折线覆盖它,按照x座标排序,我们就可以转换成求最小不下降序列的数目,这里就需要用到Dilworth定理(显然我不会。

代码

#include <cstdio>
#include <algorithm>

struct node {
	int x, y;
}p[30001];
int n, ans;
int f[30001];

bool operator <(const node &a, const node &b) {
	return a.x < b.x || (a.x == b.x && a.y > b.y);
}

int main() {
	scanf("%d", &n);
	for (int i = 1, x, y; i <= n; i++)
		scanf("%d %d", &x, &y), p[i].x = x + y, p[i].y = y - x;
	std::sort(p + 1, p + n + 1);
	f[++ans] = p[1].y;
	for (int i = 2; i <= n; i++) {
		if (p[i].y > f[ans]) f[++ans] = p[i].y;
		else f[std::lower_bound(f + 1, f + ans + 1, p[i].y) - f] = p[i].y;
	}
	printf("%d", ans);
}

日渐变菜,加油,奥利给!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章