fork download
  1. #include <vector>
  2. #include <algorithm>
  3. #include <numeric>
  4. #include <iterator>
  5. #include <iostream>
  6. #include <string>
  7. #include <cstdlib>
  8. #include <cstddef>
  9. #include <cassert>
  10. #include <cmath>
  11.  
  12. struct pos {
  13. double x, y;
  14. };
  15.  
  16. std::ostream &operator<<( std::ostream &os, const pos &p ) {
  17. os << "(" << p.x << ", " << p.y << ")";
  18. return os;
  19. }
  20.  
  21. class color {
  22. private:
  23. std::string name;
  24. explicit color( const std::string &s ): name(s) { }
  25. public:
  26. std::string get_name( ) const { return name; }
  27.  
  28. static const color BLACK;
  29. static const color RED;
  30. static const color WHITE;
  31. };
  32.  
  33. const color color::BLACK( "black" );
  34. const color color::RED( "red" );
  35. const color color::WHITE( "blue" );
  36.  
  37. std::ostream &operator<<( std::ostream &os, const color &c ) {
  38. os << c.get_name( );
  39. return os;
  40. }
  41.  
  42. class Shape {
  43. private:
  44. virtual double area_impl( ) const = 0;
  45. virtual void print_impl( std::ostream &os ) const = 0;
  46. public:
  47. double area( ) const { return area_impl( ); }
  48. void print( std::ostream &os ) const { print_impl( os ); }
  49. };
  50.  
  51. std::ostream &operator<<( std::ostream &os, const Shape &s ) {
  52. s.print( os );
  53. return os;
  54. }
  55.  
  56. class Triangle: public Shape {
  57. private:
  58. pos p[3];
  59. color col;
  60. double area_impl( ) const {
  61. double x1 = std::fabs( p[1].x-p[0].x );
  62. double x2 = std::fabs( p[2].x-p[0].x );
  63. double y1 = std::fabs( p[1].y-p[0].y );
  64. double y2 = std::fabs( p[2].y-p[0].y );
  65. return std::fabs( x1*y2 - x2*y1 )/2.0;
  66. }
  67. void print_impl( std::ostream &os ) const {
  68. os << "color=" << col << ", p[0]=" << p[0] << ", p[1]=" << p[1] << ", p[2]=" << p[2];
  69. }
  70. public:
  71. Triangle( const pos (&px)[3], const color &c ): col(c) {
  72. std::copy( px, px+3, p );
  73. }
  74. };
  75.  
  76. class Circle: public Shape {
  77. private:
  78. pos centre;
  79. double radius;
  80. color col;
  81.  
  82. double area_impl( ) const {
  83. return radius * radius * 3.14;
  84. }
  85. void print_impl( std::ostream &os ) const {
  86. os << "color=" << col << ", centre=" << centre << ", radious=" << radius;
  87. }
  88. public:
  89. Circle( const pos &c, double r, const color &cx ): centre(c), radius(r), col(cx) { }
  90. };
  91.  
  92. // ------------------------------------------------------------
  93.  
  94. namespace {
  95. static const double x_min = 0.0; // excl.
  96. static const double x_max = 500.0; // excl.
  97. static const double y_min = 0.0; // excl.
  98. static const double y_max = 600.0; // excl.
  99. static const double r_min = x_min; // excl.
  100. static const double r_max = x_max; // excl.
  101. static const unsigned int n_min = 3; // incl.
  102. static const unsigned int n_max = 10; // incl.
  103. }
  104.  
  105. double generate_random_double( double dmin, double dmax ) {
  106. double diff = dmax-dmin;
  107. double dr = static_cast<double>(std::rand( )) / RAND_MAX;
  108. if( dr == 0 ) return generate_random_double( dmin, dmax );
  109. return dmin + diff * dr;
  110. }
  111.  
  112. color generate_random_color( ) {
  113. switch( std::rand( ) % 3 ) {
  114. case 0: return color::BLACK;
  115. case 1: return color::RED;
  116. default: return color::WHITE;
  117.  
  118. }
  119. }
  120.  
  121. pos generate_random_pos( ) {
  122. pos p = { generate_random_double( x_min, x_max ), generate_random_double( y_min, y_max ) };
  123. return p;
  124. }
  125.  
  126. Triangle *generate_random_triangle( ) {
  127. color c = generate_random_color( );
  128. pos p[3];
  129. for( int i = 0; i < sizeof(p)/sizeof(p[0]); ++i ) p[i] = generate_random_pos( );
  130. return new Triangle( p, c );
  131. }
  132.  
  133. Circle *generate_random_circle( ) {
  134. color c = generate_random_color( );
  135. pos p = generate_random_pos( );
  136. double r = generate_random_double( r_min, r_max );
  137. return new Circle( p, r, c );
  138. }
  139.  
  140. int main( ) {
  141. assert( n_min >= 2 );
  142.  
  143. unsigned int n = std::rand( ) % ( n_max-n_min + 1 ) + n_min;
  144.  
  145. std::vector<Shape*> v;
  146. v.push_back( generate_random_triangle( ));
  147. v.push_back( generate_random_circle( ));
  148. for( unsigned int i = 0; i < n-2; ++i ) {
  149. if( std::rand( ) & 1 ) {
  150. v.push_back( generate_random_triangle( ));
  151. }
  152. else {
  153. v.push_back( generate_random_circle( ));
  154. }
  155. }
  156.  
  157. for( std::vector<Shape*>::iterator it = v.begin( ); it != v.end( ); ++it ) {
  158. std::cout << **it << std::endl;
  159. }
  160.  
  161. std::vector<double> areas;
  162. std::transform( v.begin( ), v.end( ), std::back_inserter( areas ), std::mem_fun( &Shape::area ));
  163. std::cout << "sum_area = " << std::accumulate( areas.begin( ), areas.end( ), 0.0 ) << std::endl;
  164.  
  165. for( std::vector<Shape*>::iterator it = v.begin( ); it != v.end( ); ++it ) {
  166. delete *it;
  167. }
  168. }
  169.  
Success #stdin #stdout 0.02s 2816KB
stdin
Standard input is empty
stdout
color=red, p[0]=(391.55, 479.064), p[1]=(455.824, 118.531), p[2]=(167.611, 460.938)
color=black, centre=(276.985, 286.438), radious=314.435
color=red, centre=(476.115, 549.717), radious=317.856
color=red, centre=(303.484, 9.78034), radious=121.443
color=black, p[0]=(78.3395, 240.567), p[1]=(64.8952, 65.2853), p[2]=(499.462, 130.954)
color=black, p[0]=(306.32, 177.619), p[1]=(318.776, 314.572), p[2]=(246.791, 583.665)
color=red, p[0]=(263.372, 461.948), p[1]=(200.114, 534.918), p[2]=(141.657, 211.475)
color=blue, centre=(34.8776, 569.596), radious=262.998
color=red, centre=(331.613, 534.14), radious=174.446
color=blue, centre=(228.851, 37.8575), radious=119.14
sum_area = 1.1123e+06