月度归档:2026年04月

洛谷P4122 [USACO17DEC] Blocked Billboard B

在漫长的挤奶过程中,奶牛 Bessie 喜欢透过谷仓的窗户盯着街对面的两块巨大的矩形广告牌,上面分别写着“Farmer Alex 的美味苜蓿”和“Farmer Greg 的优质谷物”。广告牌上这两种奶牛饲料的图片对 Bessie 来说比她农场里的草看起来美味得多。

有一天,当 Bessie 正盯着窗外时,她惊讶地看到一辆巨大的矩形卡车停在街对面。卡车的侧面有一则广告,写着“Farmer Smith 的顶级牛排”,Bessie 不太理解这则广告,但她更担心的是卡车可能会挡住她最喜欢的两块广告牌的视线。

给定两块广告牌和卡车的位置,请计算两块广告牌仍然可见的总面积。卡车可能遮挡了其中一块、两块,或者没有遮挡任何一块广告牌。

输入格式

输入的第一行包含四个用空格分隔的整数:x1​,y1​,x2​,y2​,其中 (x1​,y1​) 和 (x2​,y2​) 是 Bessie 的二维视野中第一块广告牌的左下角和右上角坐标。第二行包含四个整数,以相同的方式指定第二块广告牌的左下角和右上角坐标。第三行也是最后一行输入包含四个整数,指定卡车的左下角和右上角坐标。所有坐标都在 −1000 到 +1000 的范围内。保证两块广告牌之间没有任何重叠的正面积区域。

输出格式

请输出两块广告牌仍然可见的总面积。

输入输出样例

输入 #1

1 2 3 5
6 0 10 4
2 1 8 3

输出 #1

17

说明/提示

在这个例子中,第一块广告牌有 5 单位面积可见,第二块广告牌有 12 单位面积可见。

题目来源:Brian Dean


【代码示例】

#include <bits/stdc++.h>
using namespace std;

struct ad {
	int x1, y1, x2, y2;
} a, b, c;

int area(ad a, ad c) {
	int m_a = (a.x2 - a.x1) * (a.y2 - a.y1);
	int m_c = (c.x2 - c.x1) * (c.y2 - c.y1);
	if (c.x1 < a.x1 && c.y1 < a.y1 && c.x2 > a.x2 && c.y2 > a.y2) {
		m_a = 0;
	} else if (c.x1 > a.x1 && c.y1 > a.y1 && c.x2 < a.x2 && c.y2 < a.y2) {
		m_a -= m_c;
	} else if (c.x1 > a.x2) {
		//右侧
	} else if (c.x2 < a.x1) {
		//左侧
	} else if (c.y2 < a.y1) {
		//下方
	} else if (c.y1 > a.y2) {
		//上方
	} else {
		m_a -= (min(a.x2, c.x2) - max(a.x1, c.x1)) * (min(a.y2, c.y2) - max(a.y1, c.y1));
	}
	return m_a;
}

int main() {
	cin >> a.x1 >> a.y1 >> a.x2 >> a.y2;
	cin >> b.x1 >> b.y1 >> b.x2 >> b.y2;
	cin >> c.x1 >> c.y1 >> c.x2 >> c.y2;
	cout << area(a, c) + area(b, c) << endl;
}

整数划分问题3

有一个整数 n,请列出把整数 n 划分为若干个正整数的每一种方法,这些正整数必须选自数组 a。数组 a 中可能有重复元素,每个可以选择一次。
例如对 n = 6,a = {1, 1, 2, 2, 3, 4},n = 1 + 1 + 2 + 2 是可以的,数组 a 中有 2 个 1 和 2 个 2 可供选择;n = 2 + 2 + 2 则不正确,因为数组 a 中没有 3 个 2。

【输入格式】

输入共 2 行:
第 1 行,1 个正整数 n,k;
第 2 行,k 个正整数 a0,a1,,ak1为数组 a 中的元素。

【输出格式】

输出共若干行:
每行为用空格隔开的若干个正整数,为一种 n 划分为若干个正整数的方法,每组数按在 a 中的下标从小到大输出。若两种方法中前 k−1 个数在 a 中的下标相同,则第 k 个数的下标更小的在前。如果两种方法选取的数在 a 中的下标不全相同,则视为不同的方法。
例如对 n = 6,a = {1, 1, 2, 2, 3, 4},选取 a 的 0,2,4 或 0,3,4 号元素都会得到 n = 1 + 2 + 3,两者都要在合适的位置分别输出。

【输入输出样例#1】

输入#1

6 6
1 1 2 2 3 4

输出#1

1 1 2 2
1 1 4
1 2 3
1 2 3
1 2 3
1 2 3
2 4
2 4

【数据范围】

1n,a0,a1,,ak1109;1k20

【代码示例】

#include <bits/stdc++.h>
using namespace std;
int n, k, a[25], b[25];

void dfs(int step, int last, int sum) {
	if (step > n || last > n || sum >= k) {
		if (sum == k) {
			for (int i = 1; i < step; i++)
				cout << a[b[i]] << ' ';
			cout << endl;
			return;
		} else {
			return ;
		}

	}
	for (int i = last; i <= n; i++) {
		b[step] = i;
		dfs(step + 1, i + 1, sum + a[i]);
	}
}

int main() {
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	dfs(1, 1, 0);
}