Question:
Calculates the total area of the sum of N rectangles.
Referring to the discretization pages in the black book, I thought of the polygon Filling Algorithm in computer graphics I learned last semester.
Src:
[Cpp]
/*************************************** *****************************
Created: 2013/03/28
Created:
Filename: H: \ PE \ USA \ poj.1151.atlanta. cpp
File path: H: \ PE \ USA
File base: poj.1151.atlanta
File ext: cpp
Author: Justme0
Calculates the total area of the sum of the rectangle.
**************************************** *****************************/
// # Define ONLINE_JUDGE
# Define _ CRT_SECURE_NO_WARNINGS
# Include <iostream>
# Include <algorithm>
# Include <vector>
# Include <string>
# Include <cassert>
Using namespace std;
// Horizontal line
Struct Horizon {
Double xL; // the abscissa of the Left endpoint.
Double xR; // the abscissa of the right endpoint
Double y; // The ordinate of the horizontal line
Bool isUp; // the top or bottom of the rectangle
Horizon (): xL (0), xR (0), y (0), isUp (false ){}
Horizon (double _ xL, double _ xR, double _ y, bool _ isUp)
: XL (_ xL ),
XR (_ xR ),
Y (_ y ),
IsUp (_ isUp ){}
Bool operator <(const Horizon & other) const {
Return this-> y <other. y;
}
};
// Return: whether the input is complete
Bool input (vector <double> & xVec, vector <Horizon> & hrzVec)
{
Int cnt;
Cin> cnt;
If (0 = cnt ){
Return false;
}
Double Ax, Ay, Bx,;
While (cnt --){
Cin> Ax> Ay> Bx>;
XVec. push_back (Ax );
XVec. push_back (Bx );
HrzVec. push_back (Horizon (Ax, Bx, Ay, false ));
HrzVec. push_back (Horizon (Ax, Bx, By, true ));
}
Return true;
}
Void solve (vector <double> & xVec, const vector <Horizon> & hrzVec, double & result)
{
Result = 0;
Sort (xVec. begin (), xVec. end ());
XVec. erase (unique (xVec. begin (), xVec. end (), xVec. end ());
Sort (hrzVec. begin (), hrzVec. end ());
For (vector <double >:: size_type I = 0; I <xVec. size ()-1; ++ I ){
Double L = xVec [I];
Double R = xVec [I + 1];
Double width = R-L;
Assert (width> 0); // a unique that equals 0
Int count = 0; // counter. A positive value indicates that it is overwritten. A positive value indicates that it is not overwritten. (A count rectangle overwrites this area)
Horizon former;
For (vector <Horizon >:: size_type j = 0; j Horizon current = hrzVec [j];
If (current. xL <= L & R <= current. xR ){
Assert (count> = 0 );
If (count> 0 ){
Double height = current. y-former. y;
Assert (height> = 0 );
Result + = width * height;
}
Former = current;
Current. isUp? -- Count: ++ count;
Assert (count> = 0 );
}
}
Assert (count = 0 );
}
}
Void output (int testCase, double result)
{
Printf ("Test case # % d \ nTotal received area: %. 2f \ n", testCase, result );
}
Int main ()
{
# Ifndef ONLINE_JUDGE
Freopen ("cin.txt", "r", stdin );
# Endif
For (int testCase = 1; ++ testCase ){
Vector <double> xVec;
Vector <Horizon> hrzVec;
If (! Input (xVec, hrzVec )){
Break;
}
Double result = 0;
Solve (xVec, hrzVec, result );
Output (testCase, result );
}
Return 0;
}
/*************************************** *****************************
Created: 2013/03/28
Created:
Filename: H: \ PE \ USA \ poj.1151.atlanta. cpp
File path: H: \ PE \ USA
File base: poj.1151.atlanta
File ext: cpp
Author: Justme0
Calculates the total area of the sum of the rectangle.
**************************************** *****************************/
// # Define ONLINE_JUDGE
# Define _ CRT_SECURE_NO_WARNINGS
# Include <iostream>
# Include <algorithm>
# Include <vector>
# Include <string>
# Include <cassert>
Using namespace std;
// Horizontal line
Struct Horizon {
Double xL; // the abscissa of the Left endpoint.
Double xR; // the abscissa of the right endpoint
Double y; // The ordinate of the horizontal line
Bool isUp; // the top or bottom of the rectangle
Horizon (): xL (0), xR (0), y (0), isUp (false ){}
Horizon (double _ xL, double _ xR, double _ y, bool _ isUp)
: XL (_ xL ),
XR (_ xR ),
Y (_ y ),
IsUp (_ isUp ){}
Bool operator <(const Horizon & other) const {
Return this-> y <other. y;
}
};
// Return: whether the input is complete
Bool input (vector <double> & xVec, vector <Horizon> & hrzVec)
{
Int cnt;
Cin> cnt;
If (0 = cnt ){
Return false;
}
Double Ax, Ay, Bx,;
While (cnt --){
Cin> Ax> Ay> Bx>;
XVec. push_back (Ax );
XVec. push_back (Bx );
HrzVec. push_back (Horizon (Ax, Bx, Ay, false ));
HrzVec. push_back (Horizon (Ax, Bx, By, true ));
}
Return true;
}
Void solve (vector <double> & xVec, const vector <Horizon> & hrzVec, double & result)
{
Result = 0;
Sort (xVec. begin (), xVec. end ());
XVec. erase (unique (xVec. begin (), xVec. end (), xVec. end ());
Sort (hrzVec. begin (), hrzVec. end ());
For (vector <double >:: size_type I = 0; I <xVec. size ()-1; ++ I ){
Double L = xVec [I];
Double R = xVec [I + 1];
Double width = R-L;
Assert (width> 0); // a unique that equals 0
Int count = 0; // counter. A positive value indicates that it is overwritten. A positive value indicates that it is not overwritten. (A count rectangle overwrites this area)
Horizon former;
For (vector <Horizon >:: size_type j = 0; j Horizon current = hrzVec [j];
If (current. xL <= L & R <= current. xR ){
Assert (count> = 0 );
If (count> 0 ){
Double height = current. y-former. y;
Assert (height> = 0 );
Result + = width * height;
}
Former = current;
Current. isUp? -- Count: ++ count;
Assert (count> = 0 );
}
}
Assert (count = 0 );
}
}
Void output (int testCase, double result)
{
Printf ("Test case # % d \ nTotal received area: %. 2f \ n", testCase, result );
}
Int main ()
{
# Ifndef ONLINE_JUDGE
Freopen ("cin.txt", "r", stdin );
# Endif
For (int testCase = 1; ++ testCase ){
Vector <double> xVec;
Vector <Horizon> hrzVec;
If (! Input (xVec, hrzVec )){
Break;
}
Double result = 0;
Solve (xVec, hrzVec, result );
Output (testCase, result );
}
Return 0;
}
I can see on the Internet that some ACMER divides the program into three layers: input, problem solving, and output. I think it is quite good. I plan to do the same in the future, so that it will not be fully squeezed into a main, this also facilitates debugging. I try not to use global variables, so that the message transmission is very clear during function calls.