Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

老RE,求大神~~

Posted by level129110 at 2011-08-07 22:50:30
/*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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator