//Dawid Dworak, turbobrut na PLE #include <iostream> #include <tuple> #include <vector> #include <algorithm> #include <list> #define li long int using namespace std; vector<tuple<li,li,li,li> >rec; list<li>current; bool mniejsze(tuple <li,li,li,li>a,tuple <li,li,li,li>b){ if(get<0>(a)==get<0>(b)){ if(get<2>(a)==get<2>(b)){ if(get<1>(a)==get<1>(b)){ return get<3>(a)<get<3>(b); } return get<1>(a)<get<1>(b); } return get<2>(a)<get<2>(b); } return get<0>(a)<get<0>(b); } bool coll(li a,li b){ //indeksy if(a==b)return false; if(get<1>(rec[b]) >= get<3>(rec[a])){ return false; } if(get<3>(rec[b]) <= get<1>(rec[a])){ return false; } if(get<0>(rec[b]) >= get<2>(rec[a])){ return false; } if(get<2>(rec[b]) <= get<0>(rec[a])){ return false; } return true; } tuple<li,li,li,li> joined(li a, li b){ tuple<li,li,li,li> t=make_tuple(min(get<0>(rec[a]),get<0>(rec[b])),min(get<1>(rec[a]),get<1>(rec[b])),max(get<2>(rec[a]),get<2>(rec[b])),max(get<3>(rec[a]),get<3>(rec[b]))); //1 chyba zawsze z wczesniejszego //cout << "New rec: " << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t) << endl; return t; } int main(){ ios_base::sync_with_stdio(0); li n,x1,x2,y1,y2,maxx=0; cin >> n; for(li i=0; i<n;i++){ cin >> x1 >> x2 >> y1 >> y2; rec.push_back(make_tuple(x1,y1,x2,y2)); } sort(rec.begin(),rec.end(),mniejsze); //te indeksy obowiazuja //li pos=0; //linia li prev=0; list<li>::iterator itr=current.begin(); for(; prev<n; prev++){ //cout << prev << endl; current.push_back(prev); itr=current.begin(); bool rem=0; list<li>::iterator toRemove=current.end(); toRemove--; list<li>::iterator change=itr; while (itr!=current.end() && get<0>(rec[*itr]) < get<2>(rec[prev]) && !rem){ //jazda po liscie if(coll(*itr,prev)){ //jak sie przecinaja rec[*itr]=joined(*itr,prev); rem=1; change=itr; } itr++; } while(rem){ rem=0; current.erase(toRemove); itr=current.begin(); while(itr!=current.end() && !rem){ //look fwd if(coll(*itr,*change)){ rec[*itr]=joined(*itr,*change); rem=1; toRemove=change; change=itr; } else itr++; } } } vector<tuple<li,li,li,li> >result; list<li>::iterator itrt=current.begin(); while(itrt!=current.end()){ result.push_back(rec[*itrt]); itrt++; } sort(result.begin(),result.end(),mniejsze); li r=result.size(); cout << r << endl; for(li i=0;i<r;i++) cout << get<0>(result[i]) << " " << get<2>(result[i]) << " " << get<1>(result[i]) << " " << get<3>(result[i]) << endl; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | //Dawid Dworak, turbobrut na PLE #include <iostream> #include <tuple> #include <vector> #include <algorithm> #include <list> #define li long int using namespace std; vector<tuple<li,li,li,li> >rec; list<li>current; bool mniejsze(tuple <li,li,li,li>a,tuple <li,li,li,li>b){ if(get<0>(a)==get<0>(b)){ if(get<2>(a)==get<2>(b)){ if(get<1>(a)==get<1>(b)){ return get<3>(a)<get<3>(b); } return get<1>(a)<get<1>(b); } return get<2>(a)<get<2>(b); } return get<0>(a)<get<0>(b); } bool coll(li a,li b){ //indeksy if(a==b)return false; if(get<1>(rec[b]) >= get<3>(rec[a])){ return false; } if(get<3>(rec[b]) <= get<1>(rec[a])){ return false; } if(get<0>(rec[b]) >= get<2>(rec[a])){ return false; } if(get<2>(rec[b]) <= get<0>(rec[a])){ return false; } return true; } tuple<li,li,li,li> joined(li a, li b){ tuple<li,li,li,li> t=make_tuple(min(get<0>(rec[a]),get<0>(rec[b])),min(get<1>(rec[a]),get<1>(rec[b])),max(get<2>(rec[a]),get<2>(rec[b])),max(get<3>(rec[a]),get<3>(rec[b]))); //1 chyba zawsze z wczesniejszego //cout << "New rec: " << get<0>(t) << " " << get<1>(t) << " " << get<2>(t) << " " << get<3>(t) << endl; return t; } int main(){ ios_base::sync_with_stdio(0); li n,x1,x2,y1,y2,maxx=0; cin >> n; for(li i=0; i<n;i++){ cin >> x1 >> x2 >> y1 >> y2; rec.push_back(make_tuple(x1,y1,x2,y2)); } sort(rec.begin(),rec.end(),mniejsze); //te indeksy obowiazuja //li pos=0; //linia li prev=0; list<li>::iterator itr=current.begin(); for(; prev<n; prev++){ //cout << prev << endl; current.push_back(prev); itr=current.begin(); bool rem=0; list<li>::iterator toRemove=current.end(); toRemove--; list<li>::iterator change=itr; while (itr!=current.end() && get<0>(rec[*itr]) < get<2>(rec[prev]) && !rem){ //jazda po liscie if(coll(*itr,prev)){ //jak sie przecinaja rec[*itr]=joined(*itr,prev); rem=1; change=itr; } itr++; } while(rem){ rem=0; current.erase(toRemove); itr=current.begin(); while(itr!=current.end() && !rem){ //look fwd if(coll(*itr,*change)){ rec[*itr]=joined(*itr,*change); rem=1; toRemove=change; change=itr; } else itr++; } } } vector<tuple<li,li,li,li> >result; list<li>::iterator itrt=current.begin(); while(itrt!=current.end()){ result.push_back(rec[*itrt]); itrt++; } sort(result.begin(),result.end(),mniejsze); li r=result.size(); cout << r << endl; for(li i=0;i<r;i++) cout << get<0>(result[i]) << " " << get<2>(result[i]) << " " << get<1>(result[i]) << " " << get<3>(result[i]) << endl; } |