洛谷1034 矩形覆蓋
阿新 • • 發佈:2018-12-19
原題連結
原本以為要剪枝剪半天的一道題,結果因為資料實在是太水,裸的爆搜就能過了。。
剛打算寫個\(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; }