今天在园子里面看到有人讨论小米笔试题的解法,好吧,我不知道小米已经笔试了,
自己看了一下,试着用线段树解决,没想到掌握得还不够牢固啊.....
最终还是解决了
/******************************************* *Problem: * 一条直线有n个线段,知道首尾坐标, * 求线段总长度,重叠部分按一次算 * struct s{int start;int end;} *Author: Lei *Bolg: http://www.cnblogs.com/-Lei/ ********************************************/ #include <iostream> using namespace std; const int MAX_NODE_NUMBER=20; struct Segment { int start; int end; }; Segment segments[MAX_NODE_NUMBER]; struct TreeNode { int left; int right; int cover; }; //线段树 TreeNode tree[3*MAX_NODE_NUMBER]; void Update(int root,int left,int right) { int mid; if(tree[root].cover==0) { mid=(tree[root].left+tree[root].right)/2; if(left==tree[root].left && right==tree[root].right) tree[root].cover=1; else if(right <=mid ) Update(root*2,left,right); else if(left >= mid) Update(root*2+1,left,right); else { Update(root*2,left,mid); Update(root*2+1,mid,right); } } } int Count(int root) { if(tree[root].right-tree[root].left==1) return 0; else if(tree[root].cover==1) return tree[root].right-tree[root].left; else return Count(root*2)+Count(root*2+1); } void InitTree(int root,int left,int right) { tree[root].cover=0; tree[root].left=left; tree[root].right=right; if(tree[root].right-tree[root].left==1) return ; int mid=(left+right)/2; InitTree(root*2,left,mid); InitTree(root*2+1,mid,right); } int main() { InitTree(1,1,15); Update(1,1,4); Update(1,3,5); Update(1,2,6); Update(1,2,3); Update(1,12,13); Update(1,8,13); cout<<"Total segment length= "<<Count(1)<<endl; system("PAUSE"); return 0; }