| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
老RE,求大神~~/*poj 2528号题
运用线段树进行处理
题目意思是在砖上依次贴海报,问最后有部分或全部露除的海报数量
海报最大数量为10,000张,砖的数量为10,000,000
*/
#include<iostream>
#include<algorithm>
using namespace std;
int dld,//统计共有多少个独立端点
treenum=0;//建立树时中间方便访问的一个序号变量
struct posters{//存海报
int l,r,p1,p2;//p1,p2分别为所对应的大小序号,后来转为区间号
};
struct posterstree{//存所建的树
int l,r;
bool covered;
posterstree *left,*right;
};
posters post[10000];//存海报基本信息
posterstree posttree[20000];//存海报建立线段树的信息
int bs(int dr[],int k);//加入查找函数,为了能够不适用hash那个该死的数组~~
//////////////////////////////////////////////////////////////////
int buildtree(posterstree *tree,int l,int r);//建立树函数
bool judge(posterstree *tree,int l,int r);//判断海报是否有露出的函数
int main()
{
int testnum,//测试数据组数
n,//每组有多少张海报
qjs,//统计共分为有多少个区间
//hash[10000000],//用于存每个端点属于哪个区间进行使用的一个算是映射表吧
//该处理方式不行,需要从新建立一个新的映射关系表
paixu[20000],//为了将输入数据从小到大进行排序使用
qjb[20000];//用于存放区间的顺序关系
cin>>testnum;
while(testnum--)
{
cin>>n;//接收数据
for(int i=0;i<n;i++)
{
cin>>post[i].l>>post[i].r;
post[i].l--;post[i].r--;
paixu[2*i]=post[i].l;
paixu[2*i+1]=post[i].r;
}
//基本信息排序,去重复
sort(paixu,paixu+2*n);//注意两个函数的使用
dld=unique(paixu,paixu+2*n)-paixu;
///////////////////////////////////////////////////
//统计区间数(0号开始),与映射矩阵构建
qjs=0;
for(int i=0;i<dld-1;i++){
//hash[paixu[i]]=qjs;//端点映射
qjb[i]=qjs;
if(i<dld-1){
if(paixu[i+1]-paixu[i]==1)qjs++;
else qjs+=2;
}
}
qjb[dld-1]=qjs;
////////////////////////////////////
//海报端点对应关系确定
for(int i=0;i<=n-1;i++)
{
post[i].p1=bs(paixu,post[i].l);
post[i].p2=bs(paixu,post[i].r);
post[i].p1=qjb[post[i].p1];
post[i].p2=qjb[post[i].p2];
}
////////////////////////////////////////
//树的建立
buildtree(&posttree[0],0,qjs);
//有露出部分的海报统计
int sum=0;//露出海报的数量存储
for(int i=n-1;i>=0;i--)
{
if(judge(&posttree[0],post[i].p1,post[i].p2))sum++;
}
cout<<sum<<endl;
}
//getchar();
//getchar();
return 0;
}
////////////////////////////////////////////////////////////
//建树函数的实现
int buildtree(posterstree *tree,int l,int r)
{
tree->l=l;
tree->r=r;
tree->covered=false;
if(l==r)return 0;
treenum++;
tree->left=&posttree[treenum];
buildtree(&posttree[treenum],l,(l+r)/2);
treenum++;
tree->right=&posttree[treenum];
buildtree(&posttree[treenum],(l+r)/2+1,r);
return 0;
}
////////////////////////////////////////
//判断函数的实现
bool judge(posterstree *tree,int l,int r)
{
if(tree->covered)return false;
if(tree->l==l&&tree->r==r){
tree->covered=true;
return true;
}
bool res;//递归判断时中间参数
if(r<=(tree->l+tree->r)/2)res=judge(tree->left,l,r);
else if(l>=(tree->l+tree->r)/2+1)res=judge(tree->right,l,r);
else{
bool b1=judge(tree->left,l,(tree->l+tree->r)/2);//调试了半天出问题的地方,注意,呵呵
bool b2=judge(tree->right,(tree->l+tree->r)/2+1,r);
res=b1||b2;
};
//向上更新树的被覆盖情况
if(tree->left->covered&&tree->right->covered)tree->covered=true;
return res;
}
////////////////////////////////////////////////
//查找函数的实现
int bs(int dr[],int k)
{
int low,mid,high=dld-1;
low=0;
while(low<=high){
mid=(low+high)/2;
if(k==dr[mid])return mid;
else if(k<dr[mid])high=mid-1;
else low=mid+1;
}
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator