[Offer收割]程式設計練習賽2 hihocoder 1273 (DFS + 狀壓)
描述
小Hi實驗室所在的建築一樓有一個用於貼海報的黑板,不停的有新的海報往上貼,也會安排人員不斷的對海報進行清理,而最近,輪到了小Hi去對海報進行清理。
黑板是一塊W*H大小的區域,如果以左下角為直角座標系的話,在上次清理後第i張貼上去的海報可以視作左下角為(X1i, Y1i),右上角為(X2i, Y2i)的一個矩形。
撕去一張海報會導致所有覆蓋在其上的海報都被同時撕掉(這樣被稱為連帶,這個過程是具有傳遞性的,即如果A覆蓋B,B覆蓋C,那麼撕掉C會導致A和B均被撕掉),但是一張海報想要被手動撕掉的話需要至少存在一個角沒有被其他海報覆蓋(海報A被海報B覆蓋當且僅當他們存在面積大於0的交集並且A在B之前貼出,海報A的一個角被海報B覆蓋當且僅當這個頂點處於海報B的內部)。
於是現在問題來了,為了節約時間,小Hi決定一次性撕掉儘可能多的海報,那麼他應該選擇哪張海報呢?在效果相同的情況下,小Hi傾向於選擇更早貼出的海報。
輸入
每個輸入檔案僅包含單組測試資料。
每組測試資料的第一行為三個正整數W,H和N,分別表示黑板的寬、高以及目前張貼出的海報數量。
接下來的N行,每行為四個正整數X1i、Y1i、X2i和Y2i,描述第i張貼出的海報。
對於20%的資料,滿足1<=N<=5,1<=W,H<=10
對於100%的資料,滿足1<=N<=1000,0<=X1i, X2i <= W, 0<=Y1i, Y2i<=H, 1<=W,H<=108
輸出
對於每組測試資料,輸出兩個正整數Ans和K,表示小Hi一次最多能撕掉多少張海報,和他選擇的海報是第幾張貼出的。
6 7 4
0 0 4 4
1 0 3 4
1 4 4 6
0 0 3 5
樣例輸出
3 1
題目連結:http://hihocoder.com/problemset/problem/1273
題目分析:列舉面與面之間的覆蓋關係,用vector存,然後計算撕從開始到結束的每張海報一次能撕掉多少,這裡要注意當前海報的四個角都被覆蓋的情況,用狀態壓縮來記錄即可
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int const MAX = 1e3 + 5;
int w, h, n;
int x1[MAX], y1[MAX], x2[MAX], y2[MAX];
int cnt[MAX];
vector<int> vt[MAX];
int Cal(int i, int j)
{
int res = 0;
if(x1[i] > x1[j] && x1[i] < x2[j] && y1[i] > y1[j] && y1[i] < y2[j])
res |= 1;
if(x1[i] > x1[j] && x1[i] < x2[j] && y2[i] > y1[j] && y2[i] < y2[j])
res |= 2;
if(x2[i] > x1[j] && x2[i] < x2[j] && y2[i] > y1[j] && y2[i] < y2[j])
res |= 4;
if(x2[i] > x1[j] && x2[i] < x2[j] && y1[i] > y1[j] && y1[i] < y2[j])
res |= 8;
return res;
}
void DFS(int st, int u, int &sta)
{
cnt[u] = 1;
int sz = vt[u].size();
for(int i = 0; i < sz; i++)
{
int v = vt[u][i];
if(!cnt[v])
{
sta |= Cal(st, v);
DFS(st, v, sta);
}
}
}
int main()
{
int min_x, max_x, min_y, max_y;
scanf("%d %d %d", &w, &h, &n);
for(int i = 1; i <= n; i++)
scanf("%d %d %d %d", &x1[i], &y1[i], &x2[i], &y2[i]);
for(int i = 1; i <= n; i++)
{
for(int j = i + 1; j <= n; j++)
{
min_x = max(x1[i], x1[j]);
max_x = min(x2[i], x2[j]);
min_y = max(y1[i], y1[j]);
max_y = min(y2[i], y2[j]);
if(min_x < max_x && min_y < max_y)
vt[i].push_back(j);
}
}
int ans = 0, id = 0;
for(int i = 1; i <= n; i++)
{
int sta = 0;
memset(cnt, 0, sizeof(cnt));
DFS(i, i, sta);
if(sta == 15)
continue;
int cur = 0;
for(int j = 1; j <= n; j++)
cur += cnt[j];
if(cur > ans)
{
ans = cur;
id = i;
}
}
printf("%d %d\n", ans, id);
}
相關文章
- 團體程式設計天梯賽-練習集程式設計
- Day40--練習--程式設計2程式設計
- 團體程式設計天梯賽-練習集 L2-031 深入虎穴 (25分) dfs深搜+bfs廣搜的兩種思路程式設計
- 程式設計練習程式設計
- POJ3279 Fliptile【狀態壓縮+DFS】
- Java程式設計練習_241206Java程式設計
- 牛客練習賽27【C 水圖 dfs求最長路】
- TensorFlow2程式設計練習——多層感知機MLP程式設計
- 團體程式設計天梯賽-練習集 L1-038 新世界程式設計
- 《Python程式設計練習與解答》之程式設計概論Python程式設計
- 程式練習題(2)
- 吳恩達機器學習課程:程式設計練習 | (2) ex2-logistic regression吳恩達機器學習程式設計
- 關於程式設計的基本練習程式設計
- 程式設計師程式設計,你的練習是不是有效的?程式設計師
- 四面美團,收割 offer
- C程式設計語言(第2版·新版)練習題1-4C程式程式設計
- C程式設計語言(第2版·新版)練習題1-5C程式程式設計
- C程式設計語言(第2版·新版)練習題1-6C程式程式設計
- C程式設計語言(第2版·新版)練習題1-7C程式程式設計
- C程式設計語言(第2版·新版)練習題1-8C程式程式設計
- 序列模型第一週程式設計練習模型程式設計
- 【CCCC】PAT : 團體程式設計天梯賽-練習集 L3 答案(01-23)程式設計
- 《Java語言程式設計(基礎篇)(原書第10版)》第2~4章部分程式設計練習題程式碼Java程式設計
- wincc 7.5SP2下VBA程式設計學習練習15:批次刪除變數程式設計變數
- Java程式設計基礎24——遞迴練習Java程式設計遞迴
- 《C程式設計語言》 練習3-5C程式程式設計
- 程式設計實踐(Pandas)綜合練習1程式設計
- 大一C語言程式設計練習題C語言程式設計
- 溫度轉換——MOOC《Python語言程式設計》第1周練習題2Python程式設計
- 2020年團體程式設計天梯賽-總決賽 L2-2 口罩發放程式設計
- RecyclerView 效能優化 | 安卓 offer 收割基View優化安卓
- 牛客練習賽
- 程式設計大賽WBS程式設計
- 團體程式設計天梯賽-練習集 L1-050 倒數第N個字串 (15分)程式設計字串
- 2020年團隊程式設計天梯賽L2 -2 口罩發放程式設計
- C語言程式設計練習 GPS資料處理C語言程式設計
- 好程式設計師web前端教程分享javascript 練習題程式設計師Web前端JavaScript
- 好程式設計師web前端分享前端 javascript 練習題程式設計師Web前端JavaScript
- LeetCode演算法練習——深度優先搜尋 DFSLeetCode演算法