您的位置:首页 > 其它

Hihocoder hiho一下 第140周 清理海报

2017-03-13 18:06 253 查看


题目1 : 清理海报

时间限制:5000ms
单点时限:1000ms
内存限制:256MB


描述

小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


先根据判断两个海报是否相交和四角的覆盖---得到最后那些可以当做撕海报的源点---和海报之间的联通性---

然后从每个海报源点开始dfs-.-  最后统计最大值

代码:

#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
int x1,x2,y1,y2;
bool jiao[4];
}book[1010];
bool pan(int i,int j)
{
if (book[i].x1>=book[j].x2||book[i].x2<=book[j].x1||book[i].y1>=book[j].y2||book[i].y2<=book[j].y1)
return false;
if (book[i].y1<book[j].y2&&book[i].y1>book[j].y1)
{
if (book[i].x1>book[j].x1&&book[i].x1<book[j].x2)
book[i].jiao[0]=true;
if (book[i].x2>book[j].x1&&book[i].x2<book[j].x2)
book[i].jiao[1]=true;
}
if (book[i].y2<book[j].y2&&book[i].y2>book[j].y1)
{
if (book[i].x1>book[j].x1&&book[i].x1<book[j].x2)
book[i].jiao[2]=true;
if (book[i].x2>book[j].x1&&book[i].x2<book[j].x2)
book[i].jiao[3]=true;
}
return true;
}
bool fa[1010];
int ans1,ans2,wx;
vector<int > V[1010];
void dfs(int x)
{
fa[x]=true;
ans2++;
for (int i=0;i<V[x].size();i++)
{
int v=V[x][i];
if (fa[v]) continue;
dfs(v);
}
}
int main()
{
int w,h,n;
cin>>w>>h>>n;
for (int i=1;i<=n;i++)
cin>>book[i].x1>>book[i].y1>>book[i].x2>>book[i].y2;
for (int i=1;i<n;i++)
{
for (int j=i+1;j<=n;j++)
{
if (pan(i,j))
{
V[i].push_back(j);
}
}
}
bool fafe;
ans1=0;
for (int i=1;i<=n;i++)
{
fafe=false;
for (int j=0;j<4;j++)
if (!book[i].jiao[j])
{
fafe=true;
break;
}
if (fafe)
{
fill(fa,fa+n+1,false);
ans2=0;dfs(i);
if (ans2>ans1)
{
ans1=ans2;
wx=i;
}
}
}
cout<<ans1<<' '<<wx<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: