一名苦逼的OIer,想成为ACMer

Iowa_Battleship

洛谷1034 矩形覆盖

原题链接

原本以为要剪枝剪半天的一道题,结果因为数据实在是太水,裸的爆搜就能过了。。
刚打算写个\(HASH\)去重,结果看时间不够就随便交一发,然后就\(A\)了。。(捂脸
爆搜就直接搜每个点在哪个矩阵里,同时更新答案即可。
因为过了,所以就懒得写剪枝和去重了

#include<cstdio>
using namespace std;
const int N = 55;
struct poi {
	int x, y;
};
poi a[N];
struct squ {
	int x_mi, x_ma, y_mi, y_ma, s;
	bool p;
	squ() { x_mi = y_mi = 1e9; }
};
squ jz[5];
int n, k, mi = 1e9;
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
inline void ckmaxn(int &x, int y) { if (x < y) x = y; }
inline void ckminn(int &x, int y) { if (x > y) x = y; }
inline bool judge()
{
	for (int i = 1; i < k; i++)
		for (int j = i + 1; j <= k; j++)
		{
			if (!jz[i].p || !jz[j].p)
				continue;
			if (jz[i].x_ma >= jz[j].x_mi && jz[j].x_ma >= jz[i].x_mi && jz[i].y_ma >= jz[j].y_mi && jz[j].y_ma >= jz[i].y_mi)
				return false;
		}
	return true;
}
void dfs(int nw, int s)
{
	if (s >= mi)
		return;
	if (nw > n)
	{
		mi = s;
		return;
	}
	for (int i = 1; i <= k; i++)//搜这个点在哪个矩阵
	{
		if (a[nw].x <= jz[i].x_ma && a[nw].y <= jz[i].y_ma && a[nw].x >= jz[i].x_mi && a[nw].y >= jz[i].y_mi)//如果在原本范围就直接扔进去,其实这里可以加一个剪枝,因为已经在一个矩阵里的点显然不能给其它矩阵
			dfs(nw + 1, s);
		else//如果在该矩阵之外就扩展这个矩阵
		{
			squ o = jz[i];
			ckmaxn(jz[i].x_ma, a[nw].x);
			ckmaxn(jz[i].y_ma, a[nw].y);
			ckminn(jz[i].x_mi, a[nw].x);
			ckminn(jz[i].y_mi, a[nw].y);
			jz[i].p = 1;//判断是否已经覆盖了点,使没有覆盖点的矩阵在judge中跳过
			if (judge())//判断是否有矩阵重合
				dfs(nw + 1, s - o.s + (jz[i].s = (jz[i].x_ma - jz[i].x_mi) * (jz[i].y_ma - jz[i].y_mi)));
			jz[i] = o;
		}
	}
}
int main()
{
	int i;
	n = re(); k = re();
	for (i = 1; i <= n; i++)
		a[i].x = re(), a[i].y = re();
	dfs(1, 0);
	printf("%d", mi);
	return 0;
}

posted on 2018-12-19 21:19  Iowa_Battleship  阅读(141)  评论(0编辑  收藏  举报

导航