Hướng dẫn giải của Diện tích hình chữ nhật
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này
Code mẫu của flashmt
uses math; const fi=''; fo=''; maxn=10010; type ar=array[1..maxn*2] of longint; var n,nh,nv,re:longint; x,y,h,v,d,e,xx,yy:ar; a,s:array[1..maxn*10] of longint; procedure rf; var i:longint; begin read(n); for i:=1 to n do begin read(x[i*2-1],y[i*2-1],x[i*2],y[i*2]); xx[i*2-1]:=x[i*2]; xx[i*2]:=x[i*2-1]; end; for i:=1 to n*2 do begin h[i]:=y[i]; v[i]:=x[i]; d[i]:=i; e[i]:=i; end; end; procedure sort(var h,d:ar;l,r:longint); var i,j,x,y:longint; begin i:=l; j:=r; x:=h[(i+j) shr 1]; repeat while h[i]<x do inc(i); while h[j]>x do dec(j); if i<=j then begin y:=h[i]; h[i]:=h[j]; h[j]:=y; y:=d[i]; d[i]:=d[j]; d[j]:=y; inc(i); dec(j); end; until i>j; if i<r then sort(h,d,i,r); if l<j then sort(h,d,l,j); end; procedure roirac; var i:longint; begin sort(h,d,1,n*2); nh:=1; y[d[1]]:=1; for i:=2 to n*2 do begin if h[i]<>h[nh] then begin inc(nh); h[nh]:=h[i]; end; y[d[i]]:=nh; end; for i:=1 to n do dec(y[2*i]); for i:=1 to n do begin yy[i*2-1]:=y[i*2]; yy[i*2]:=y[i*2-1]; end; end; procedure add(node,l,r,x,y,val:longint); var mid:longint; begin if (l=x) and (r=y) then begin a[node]:=a[node]+val; if a[node]=1 then s[node]:=h[r+1]-h[l]; if a[node]=0 then begin if l<r then s[node]:=s[node shl 1]+s[node shl 1+1] else s[node]:=0; end; end else begin mid:=(l+r) shr 1; if x<=mid then add(node shl 1,l,mid,x,min(y,mid),val); if y>mid then add(node shl 1+1,mid+1,r,max(x,mid+1),y,val); if a[node]=0 then s[node]:=s[node shl 1]+s[node shl 1+1]; end; end; procedure pr; var i,t:longint; begin roirac; sort(v,e,1,n*2); for i:=1 to n*2 do begin if i>1 then re:=re+(v[i]-v[i-1])*s[1]; t:=e[i]; if xx[t]>x[t] then add(1,1,n*2-1,y[t],yy[t],1) else add(1,1,n*2-1,yy[t],y[t],-1); end; writeln(re); end; begin assign(input,fi); reset(input); rf; pr; close(input); end.
Code mẫu của ladpro98
#include <bits/stdc++.h> #define ii pair<int, int> #define iiii pair<pair<int, int> , pair<int, int> > #define X first #define Y second const int xxx = 33333; const int Open = 1; const int Close = -1; using namespace std; vector<iiii> event; ii it[8*xxx]; int n, res; void Enter() { //freopen("AREA.inp", "r", stdin); scanf("%d\n", &n); int i, x1, y2, x2, y1; for(i=1; i<=n; i++) { scanf("%d %d %d %d\n", &x1, &y1, &x2, &y2); event.push_back(iiii(ii(x1, Open), ii(y1, y2))); event.push_back(iiii(ii(x2, Close), ii(y1, y2))); } sort(event.begin(), event.end()); } void Upd(int k, int l, int r, int i, int j, int v) { if (r<=i || j<=l) return; if (i<=l && r<=j ) it[k].X += v; else { int m = (l+r) >> 1; Upd(k << 1, l, m, i, j, v); Upd((k << 1) | 1, m, r, i, j, v); } if (it[k].X == 0) it[k].Y = it[k << 1].Y + it[(k << 1) | 1].Y; else it[k].Y = r - l; } void SweepLine() { int i, y1, y2, type, len, d; for(i=0; i<(event.size()-1); i++) { y1 = event[i].Y.X; y2 = event[i].Y.Y; type = event[i].X.Y; Upd(1, 0, xxx, y1, y2, type); len = event[i+1].X.X - event[i].X.X; d = it[1].Y; res += len * d; } } int main() { Enter(); SweepLine(); printf("%d", res); return 0; }
Code mẫu của RR
uses math; var res,now,n,i,x1,y1,x2,y2,m:longint; sl,sum:array[1..131072] of longint; x,u,v,typ:array[1..20111] of longint; procedure swap(var a,b:longint); var tmp:longint; begin tmp:=a; a:=b; b:=tmp; end; procedure sort(l,r:longint); var i,j,mid:longint; begin i:=l; j:=r; mid:=x[l+random(r-l+1)]; repeat while x[i]<mid do inc(i); while x[j]>mid do dec(j); if i<=j then begin swap(x[i],x[j]); swap(u[i],u[j]); swap(v[i],v[j]); swap(typ[i],typ[j]); inc(i); dec(j); end; until i>j; if i<r then sort(i,r); if l<j then sort(l,j); end; procedure update(u,v,k,i,l,r:longint); var mid:longint; begin if (v<l) or (r<u) then exit; if (u<=l) and (r<=v) then begin inc(sl[i],k); if sl[i]>0 then sum[i]:=r-l+1 else sum[i]:=sum[i*2]+sum[i*2+1]; exit; end; mid:=(l+r) shr 1; update(u,v,k,i*2,l,mid); update(u,v,k,i*2+1,mid+1,r); if sl[i]=0 then sum[i]:=sum[i*2]+sum[i*2+1] else sum[i]:=r-l+1; end; begin read(n); m:=0; for i:=1 to n do begin read(x1,y1,x2,y2); inc(x1); inc(y1); inc(x2); inc(m); x[m]:=x1; u[m]:=y1; v[m]:=y2; typ[m]:=1; inc(m); x[m]:=x2; u[m]:=y1; v[m]:=y2; typ[m]:=-1; end; sort(1,m); now:=1; res:=0; for i:=1 to 30111 do begin while (x[now]=i) do begin update(u[now],v[now],typ[now],1,1,30111); inc(now); end; inc(res,sum[1]); end; writeln(res); end.
Code mẫu của ll931110
Program AREA; Const input = ''; output = ''; Type rec = record low: longint; high: longint; open: boolean; end; arr = array[1..200000] of longint; Var x,number,cover,c: arr; lab: array[1..200000] of rec; n: longint; S: int64; Procedure init; Var f: text; i: longint; x1,y1,x2,y2: longint; Begin Assign(f, input); Reset(f); Readln(f, n); For i:= 1 to n do Begin Read(f, x1, y1, x2, y2); x[2 * i - 1]:= x1; x[2 * i]:= x2; with lab[2 * i - 1] do Begin low:= y1; high:= y2; open:= true; End; with lab[2 * i] do Begin low:= y1; high:= y2; open:= false; End; c[2 * i - 1]:= y1; c[2 * i]:= y2; End; Close(f); Fillchar(number, sizeof(number), 0); Fillchar(cover, sizeof(cover), 0); End; Procedure quicksort1; Procedure partition(l,h: longint); Var i,j,p,temp1: longint; temp2: rec; Begin If l >= h then exit; i:= l; j:= h; p:= x[random(h - l + 1) + l]; Repeat While x[i] < p do inc(i); While x[j] > p do dec(j); If i <= j then Begin If i < j then Begin temp1:= x[i]; x[i]:= x[j]; x[j]:= temp1; temp2:= lab[i]; lab[i]:= lab[j]; lab[j]:= temp2; End; inc(i); dec(j); End; Until i > j; partition(l,j); partition(i,h); End; Begin partition(1,2 * n); End; Procedure quicksort2; Procedure partition(l,h: longint); Var i,j,p,temp1: longint; Begin If l >= h then exit; i:= l; j:= h; p:= c[random(h - l + 1) + l]; Repeat While c[i] < p do inc(i); While c[j] > p do dec(j); If i <= j then Begin If i < j then Begin temp1:= c[i]; c[i]:= c[j]; c[j]:= temp1; End; inc(i); dec(j); End; Until i > j; partition(l,j); partition(i,h); End; Begin partition(1,2 * n); End; Procedure open_true(A, B, k, l, h: longint); Var mid: longint; Begin If (h <= c[A]) or (c[B] <= l) then exit; If (l <= c[A]) and (c[B] <= h) then Begin inc(number[k]); cover[k]:= c[B] - c[A]; exit; End; If A + 1 >= B then exit; mid:= (A + B) div 2; open_true(A, mid, 2 * k, l, h); open_true(mid, B, 2 * k + 1, l, h); If number[k] = 0 then cover[k]:= cover[2 * k] + cover[2 * k + 1]; End; Procedure open_false(A, B, k, l, h: longint); Var mid: longint; Begin If (h <= c[A]) or (c[B] <= l) then exit; If (l <= c[A]) and (c[B] <= h) then Begin dec(number[k]); If number[k] = 0 then cover[k]:= cover[2 * k] + cover[2 * k + 1]; exit; End; If A + 1 >= B then Begin cover[k]:= 0; exit; End; mid:= (A + B) div 2; open_false(A, mid, 2 * k, l, h); open_false(mid, B, 2 * k + 1, l, h); If number[k] = 0 then cover[k]:= cover[2 * k] + cover[2 * k + 1]; End; Procedure solve; Var f: text; i: longint; Begin Assign(f, output); Rewrite(f); quicksort1; quicksort2; open_true(1, 2 * n, 1, lab[1].low, lab[1].high); S:= 0; For i:= 2 to 2 * n do Begin S:= S + cover[1] * (x[i] - x[i - 1]); If lab[i].open then open_true(1, 2 * n, 1, lab[i].low, lab[i].high) else open_false(1, 2 * n, 1, lab[i].low, lab[i].high); End; Writeln(f, S); Close(f); End; Begin init; solve; End.
Code mẫu của skyvn97
#include<cassert> #include<cstdio> #include<vector> #define MAX 30030 #define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i=i+1) #define REP(i,n) for (int i=0,_n=(n);i<_n;i=i+1) using namespace std; class SegmentTree { private: vector<int> cnt,add; int n; void update(int i,int l,int r,int u,int v,int c) { if (l>v || r<u || l>r || v<u) return; assert(0<=i && i<cnt.size()); if (u<=l && r<=v) { add[i]+=c; return; } int m=(l+r)>>1; update(2*i,l,m,u,v,c); update(2*i+1,m+1,r,u,v,c); int L=add[2*i]>0?m-l+1:cnt[2*i]; int R=add[2*i+1]>0?r-m:cnt[2*i+1]; cnt[i]=L+R; } public: SegmentTree() { n=0; } SegmentTree(int n) { this->n=n; cnt.assign(4*n+7,0); add.assign(4*n+7,0); } void update(int l,int r,int v) { update(1,1,n,l,r,v); } int countCell(void) const { return (add[1]>0?n:cnt[1]); } }; struct Event { int l,r,v; Event() { l=r=v=0; } Event(int _l,int _r,int _v) { l=_l;r=_r;v=_v; } }; struct Rectangle { int x1,y1,x2,y2; Rectangle() { x1=y1=x2=y2=0; } void input(void) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); x1++;y1++; } bool valid(void) const { return (x1<=x2 && y1<=y2); } }; Rectangle rec[MAX+7]; vector<Event> event[MAX+7]; int n; void init(void) { scanf("%d",&n); FOR(i,1,n) rec[i].input(); } void process(void) { FOR(i,1,n) if (rec[i].valid()) { event[rec[i].x1].push_back(Event(rec[i].y1,rec[i].y2,1)); event[rec[i].x2+1].push_back(Event(rec[i].y1,rec[i].y2,-1)); } SegmentTree segTree(MAX); int res=0; FOR(i,1,MAX) { REP(j,event[i].size()) segTree.update(event[i][j].l,event[i][j].r,event[i][j].v); res+=segTree.countCell(); } printf("%d\n",res); } int main(void) { init(); process(); return 0; }
Code mẫu của khuc_tuan
#include <iostream> using namespace std; #define mn 20001 #define mt 131071 typedef struct{ int num,val; } data; typedef struct{ int x1,x2,y; bool io; } vertex; data d[mt]; vertex a[mn]; int n; inline void update(int k,int first,int last,int u,int v,bool is_open){ if (first>v||last<u) return ; int n1=k<<1,n2=1+(k<<1); if (first>=u&&last<=v){ if (is_open){ if (!(d[k].num++)) d[k].val=last-first; } else{ if (!(--d[k].num)) d[k].val=d[n1].val+d[n2].val; } return ; } int mid=(first+last)>>1; if (first<mid){ update(n1,first,mid,u,v,is_open); update(n2,mid,last,u,v,is_open); if (!(d[k].num)) d[k].val=d[n1].val+d[n2].val; } } inline bool cmp(vertex u,vertex v){ if (u.y<v.y) return(true); return(false); } inline void cal(){ int area=0; for(int i=1;i<(n<<1);i++){ update(1,0,30000,a[i].x1,a[i].x2,a[i].io); area+=(a[i+1].y-a[i].y)*d[1].val; } printf("%d",area); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d%d%d",&a[i].x1,&a[i].y,&a[i].x2,&a[i+n].y); a[i+n].x1=a[i].x1;a[i+n].x2=a[i].x2; a[i].io=true;a[i+n].io=false; } sort(a+1,a+1+(n<<1),cmp); cal(); }
Bình luận