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 |
考虑了边重合的的算法1.此题数据没有考虑边重合现象 2.网上的大部分解法也没有考虑到边重合现象 因为,我修改了网上的解法,分衡量和纵向两次分别求出横向部分的周长以及纵向部分的周长,然后相加就得到结果。 #include <iostream> #include <algorithm> using namespace std; const int N = 5010; struct Line { int start, end; int dim; bool in; bool operator<(const Line & a) const { return dim < a.dim; } }; Line line[2*N]; int val[2*N]; int X[2*N]; int Y[2*N]; int n, val_size; struct Node { int left, right, len; int seg_num, cover_len; int cover; bool lcover, rcover; Node() { left = right = 0; len = seg_num = cover_len = cover = 0; lcover = rcover = false; } }; class SegTree { private: int max_val; Node tree[8*N]; void get_cover_len(int num); void get_seg_num(int num); public: SegTree(int val = 0); void build(int l, int r, int num); void insert(int l, int r, int num); void del(int l, int r, int num); int get_cover_len() { return tree[1].cover_len; } int get_seg_num() { return tree[1].seg_num; } }; SegTree::SegTree(int v) { max_val = v; build(0, v-1, 1); } void SegTree::get_cover_len(int num) { if(tree[num].cover > 0) tree[num].cover_len = tree[num].len; else if(tree[num].right - tree[num].left > 1) tree[num].cover_len = tree[2*num].cover_len + tree[2*num+1].cover_len; else tree[num].cover_len = 0; } void SegTree::get_seg_num(int num) { if(tree[num].cover > 0) { tree[num].lcover = tree[num].rcover = true; tree[num].seg_num = 1; } else if(tree[num].right - tree[num].left > 1) { tree[num].lcover = tree[2*num].lcover; tree[num].rcover = tree[2*num+1].rcover; tree[num].seg_num = tree[2*num].seg_num + tree[2*num+1].seg_num - (tree[2*num].rcover * tree[2*num+1].lcover); } else { tree[num].lcover = tree[num].rcover = false; tree[num].seg_num = 0; } } void SegTree::build(int l, int r, int num) { tree[num].left = l; tree[num].right = r; tree[num].len = val[r] - val[l]; if(r - l > 1) { int mid = (l + r) >> 1; build(l, mid, 2*num); build(mid, r, 2*num+1); } } void SegTree::insert(int l, int r, int num) { if(tree[num].left == l && tree[num].right == r) { tree[num].cover ++; } else { int mid = (tree[num].left + tree[num].right) >> 1; if(r <= mid) insert(l, r, 2*num); else if(l >= mid) insert(l, r, 2*num+1); else { insert(l, mid, 2*num); insert(mid, r, 2*num+1); } } get_cover_len(num); get_seg_num(num); } void SegTree::del(int l, int r, int num) { if(tree[num].left + 1 == tree[num].right) { if(tree[num].cover > 0) tree[num].cover --; } else { if(tree[num].cover > 0) { tree[num].cover --; tree[2*num].cover ++; tree[2*num+1].cover ++; } int mid = (tree[num].left + tree[num].right) >> 1; if(r <= mid) { del(l, r, 2*num); get_cover_len(2*num+1); get_seg_num(2*num+1); } else if(l >= mid) { del(l, r, 2*num+1); get_cover_len(2*num); get_seg_num(2*num); } else { del(l, mid, 2*num); del(mid, r, 2*num+1); } } get_cover_len(num); get_seg_num(num); } int get_res() { int total = 0; SegTree seg_tree(val_size); for(int i=0; i<2*n-1; i++) { int start = lower_bound(val, val+val_size, line[i].start) - val; int end = lower_bound(val, val+val_size, line[i].end) - val; if(line[i].in) seg_tree.insert(start, end, 1); else seg_tree.del(start, end, 1); total += seg_tree.get_seg_num() * (line[i+1].dim - line[i].dim) * 2; } return total; } int get_horizon_len() { for(int i=0; i<n; i++) { line[2*i].start = Y[2*i]; line[2*i].end = Y[2*i+1]; line[2*i].dim = X[2*i]; line[2*i].in = true; line[2*i+1].start = Y[2*i]; line[2*i+1].end = Y[2*i+1]; line[2*i+1].dim = X[2*i+1]; line[2*i+1].in = false; val[2*i] = Y[2*i]; val[2*i+1] = Y[2*i+1]; } sort(line, line+2*n); sort(val, val+2*n); val_size = unique(val, val+2*n) - val; return get_res(); } int get_verticle_len() { for(int i=0; i<n; i++) { line[2*i].start = X[2*i]; line[2*i].end = X[2*i+1]; line[2*i].dim = Y[2*i]; line[2*i].in = true; line[2*i+1].start = X[2*i]; line[2*i+1].end = X[2*i+1]; line[2*i+1].dim = Y[2*i+1]; line[2*i+1].in = false; val[2*i] = X[2*i]; val[2*i+1] = X[2*i+1]; } sort(line, line+2*n); sort(val, val+2*n); val_size = unique(val, val+2*n) - val; return get_res(); } int main() { cin >> n; int x1, y1, x2, y2; for(int i=0; i<n; i++) { cin >> X[2*i] >> Y[2*i] >> X[2*i+1] >> Y[2*i+1]; } /* cout << "Verticle:" << endl; cout << get_verticle_len() << endl; cout << "Hozrizontal:" << endl; cout << get_horizon_len() << endl; */ cout << get_verticle_len() + get_horizon_len() << endl; return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator