記錄一個菜逼的成長。。
題目連結
官方題解
題解裡面貌似有錯
這裡應該還有條3->4的邊
有人會問為什麼會有2->4這條邊,從圖上看2的四個點都被覆寫了。
這就是建圖時要注意的地方了,建圖時我們隻要根據兩個矩形是否相交建圖就可以了,不必去管矩形的四個點是否被覆寫。
因為雖然2的四個點都被覆寫,但是2是作為1和4之間的關聯的。撕1時,會先撕去2,然後再撕去4.是以這裡要有條2->4的邊。這樣在搜尋時就不會漏了。
然後枚舉第一次要撕去的海報,這裡判斷一下矩形的四個點是否被覆寫。
隻要有一個點未被覆寫就可以直接去搜尋了。
PS:這裡我用y1數組不知道為什麼會CE..說定義重了。然而程式裡隻定義了一次。。
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn = + ;
int x1[maxn],y11[maxn],x2[maxn],y2[maxn];
int f[maxn][],vis[maxn];
vector<int>g[maxn];
int w,h,n;
bool overlap(int i, int j)
{
return !(x1[i] >= x2[j] || x1[j] >= x2[i] || y11[i] >= y2[j] || y11[j] >= y2[i]);
}
bool check(int i,int x,int y)
{
return x >= x1[i] && x <= x2[i] && y >= y11[i] && y <= y2[i];
}
int dfs(int x)
{
int ans = ;
for( int i = ; i < g[x].size(); i++ ){
if(!vis[g[x][i]]){
vis[g[x][i]] = ;
ans += dfs(g[x][i]);
}
}
return ans + ;
}
int main()
{
while(~scanf("%d%d%d",&w,&h,&n)){
for( int i = ; i <= n; i++ ){
scanf("%d%d%d%d",&x1[i],&y11[i],&x2[i],&y2[i]);
}
for( int i = ; i <= n; i++ ){
for( int j = i+; j <= n; j++ ){
if(check(j,x1[i],y11[i]))f[i][] = ;
if(check(j,x1[i],y2[i]))f[i][] = ;
if(check(j,x2[i],y2[i]))f[i][] = ;
if(check(j,x2[i],y11[i]))f[i][] = ;
}
}
for( int i = ; i <= n; i++ ){
for( int j = ; j < i; j++ ){
if(overlap(i,j))g[j].pb(i);
}
}
int mx = -;
int id;
for( int i = ; i <= n; i++ ){
if(f[i][] && f[i][] && f[i][] && f[i][])continue;
cl(vis,);
int ret = dfs(i);
if(ret > mx){
mx = ret;
id = i;
}
}
printf("%d %d\n",mx,id);
}
return ;
}