I have got a problem to check if three points form a triangle or not. If it forms a triangle the program should print the square of maximum length of the three sides of the triangle. If not the program will print "Coolinear". Anyways here is a sample of what I have tried:
#include <iostream>
#include <cmath>
using namespace std;
int main () {
double x1,y1,x2,y2,x3,y3;
double area;
double s1,s2,s3;
cin >> x1 >> y1;
cin >> x2 >> y2;
cin >> x3 >> y3;
area = 0.5*abs(((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)));
s1 = ((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2));
s2 = ((x2-x3)*(x2-x3))+((y2-y3)*(y2-y3));
s3 = ((x1-x3)*(x1-x3))+((y1-y3)*(y1-y3));
if (area!=0){
if (s1 >= s2 && s1 >= s3)
cout<<s1<<endl;
if (s2 >= s1 && s2 >= s3)
cout<<s2<<endl;
if (s3 >= s1 && s3 >= s2)
cout <<s3<<endl;
}
else
cout <<"Coollinear";
return 0;
}
I submitted this code on codeforces website as it is my last problem on a contest. It gives me wrong answer at test 9, What else should I use? and Why is my answer wrong?
Anyways Here is the text of the problem:
Like all problem solvers, Meiko loves eating crepe! As we all know, crepe usually served in a triangular shape. Now Meiko wants to know how large can a crepe side be! So he tries to draw a triangle on a plane using three points and calculate the maximum length of the three sides of the triangle. But sometimes he falls asleep as he has been busy with the team preparing the training problems! As a result, the three points he uses may not form a triangle that could represent a piece of crepe! A triangle can represent a piece of crepe only if it has a positive area. So you are here to help Meiko! Given the coordinates Meiko used, determine whether they form a triangle that could represent a piece of crepe or not.
Input
Three integer coordinates (X,Y) that represent the three points Meiko used. Each point on a separate line. (-10^9<=X,Y<=10^9)
Output
If the points form a triangle that can represent a piece of crepe, print the square of the maximum length of the three sides of the triangle. Otherwise print "Collinear" without quotes.
If at least two sides have same length and are longer than the third one then this code will output multiple results. The three if-statements must be fixed
#include <iostream>
#include <cmath>
using namespace std;
int main () {
double x1,y1,x2,y2,x3,y3;
double area;
double s1,s2,s3;
cin >> x1 >> y1;
cin >> x2 >> y2;
cin >> x3 >> y3;
area = 0.5*abs(((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)));
s1 = ((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2));
s2 = ((x2-x3)*(x2-x3))+((y2-y3)*(y2-y3));
s3 = ((x1-x3)*(x1-x3))+((y1-y3)*(y1-y3));
if (area!=0){
if (s1 >= s2 && s1 >= s3)
cout<<s1<<endl;
else if (s2 >= s1 && s2 >= s3)
cout<<s2<<endl;
else if (s3 >= s1 && s3 >= s2)
cout <<s3<<endl;
}
else
cout <<"Coollinear";
return 0;
}
Your code will output multiple results if the maximum length is not unique.
You can get rid of the complicated logic:
#include <algorithm>
//...
if (area == 0) {
cout << "Collinear";
}
else {
cout << max({s1, s2, s3}));
}
Late addendum, in case this hasn't been solved yet (and I can't sleep):
The clue to solving this is in the word "integers" in the description.
The test case you're failing on has been constructed so that
(x2-x1)*(y3-y1)-(x3-x1)*(y2-y1)
is non-zero when using floating point, and zero when using integers.
You don't need 0.5 * abs(... to determine whether the area is zero or not, and I expect the following to work:
#include <algorithm>
#include <iostream>
using namespace std;
int square(int x) { return x * x; }
int main () {
int x1, y1, x2, y2, x3, y3;
cin >> x1 >> y1;
cin >> x2 >> y2;
cin >> x3 >> y3;
int area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
if (area != 0){
int s1 = square(x1 - x2) + square(y1 - y2);
int s2 = square(x2 - x3) + square(y2 - y3);
int s3 = square(x1 - x3) + square(y1 - y3);
cout << max(s1, max(s2, s3));
}
else
{
cout <<"Collinear";
}
}
Related
Is there any mistake in that Cpp-code, which can lead unfavorable output ?
Actually while submitting its solution...I got 6 wrong test cases, but I am not able to find any error!
I'm providing question(commented) for reference,
/* You are choreographing a circus show with various animals. For one act, you are given two
kangaroos on a number line ready to jump in the positive direction (i.e, toward positive infinity).
The first kangaroo starts at location x1 and moves at a rate of v1 meters per jump.
The second kangaroo starts at location x2 and moves at a rate of v2 meters per jump.
You have to figure out a way to get both kangaroos at the same location at the same time as part of
the show. If it is possible, return YES, otherwise return NO.
*/
#include <iostream>
int main()
{
int x1, v1, x2, v2;
std::cout << "ENTER FIRST STARTING POS THEN ITS SPEED:"<< std::endl;
std::cin >> x1 >> v1;
std::cout << "ENTER SECOND STARTING POS THEN ITS SPEED:"<< std::endl;
std::cin >> x2 >> v2;
int max, min;
(v1 > v2) ? max = x1, min = x2 : max = x2, min = x1;
while ((x1 != x2) && (min > max))
{
if (max == x1)
{
max = max + v1;
min = min + v2;
}
else
{
max = max + v2;
min = min + v1;
}
x1 = x1 + v1;
x2 = x2 + v2;
}
if (max == min)
{
std::cout << "YES";
}
else
std::cout << "NO";
return (0);
}
Initial remark:
You want to check if there exists an integer n with
x1 + n * v1 = x2 + n * v2
In other words:
x1 - x2 = n(v2 - v1)
Now if v1 != v2 and (x1 - x2) / (v2 - v1) is an integer (or (x1 - x2) % (v2 - v1) == 0), the answer is YES.
If v1 == v2 and x1 == x2, the answer is also YES
In all other cases, the answer is NO.
Trying to calculate this using a loop isn't exactly an optimal approach.
Now to your code. And I must admit I didn't spot the mistake yet, but I have a few comments on it.
You terminate your loop as soon as either x1 == x2 or min <= max.
We'll have to think about the meaning of the variables here.
x1 is the position of kangaroo1
x2 is the position of kangaroo2
Obviously, if both are equal, you have a "hit" (answer is YES).
min is the position of the slower kangaroo
max is the position of the faster kangaroo
As a hint, it would be a good idea to choose names that reflect this meaning. min and max aren't that well chosen.
The double bookkeeping doesn't make it easier to understand what's going on (you keep the same position in two variables), and the comparison to check which velocity is which doesn't add to clarity.
Let me rewrite your algorithm a little
/* You are choreographing a circus show with various animals. For one act, you are given two
kangaroos on a number line ready to jump in the positive direction (i.e, toward positive infinity).
The first kangaroo starts at location x1 and moves at a rate of v1 meters per jump.
The second kangaroo starts at location x2 and moves at a rate of v2 meters per jump.
You have to figure out a way to get both kangaroos at the same location at the same time as part of
the show. If it is possible, return YES, otherwise return NO.
*/
#include <iostream>
int main()
{
int pos_fast, v_fast, pos_slow, v_slow;
int x1, v1, x2, v2;
std::cout << "ENTER FIRST STARTING POS THEN ITS SPEED:"<< std::endl;
std::cin >> x1 >> v1;
std::cout << "ENTER SECOND STARTING POS THEN ITS SPEED:"<< std::endl;
std::cin >> x2 >> v2;
// find out who's fast and who's slow
if (v1 > v2) {
pos_fast = x1;
v_fast = v1;
pos_slow = x2;
v_slow = v2;
} else {
pos_fast = x2;
v_fast = v2;
pos_slow = x1;
v_slow = v1;
}
// now if v1 == v2, we could end up in an endless loop
// So we won't let them run if they are equally fast
if (v_fast != v_slow) {
// let them jump until the faster kangaroo isn't behind the slower one any more
while (pos_fast < pos_slow) {
pos_fast = pos_fast + v_fast;
pos_slow = pos_slow + v_slow;
}
}
// and if both kangaroos now have a headache, the answer is YES ;-)
if (pos_fast == pos_slow) {
std::cout << "YES";
} else {
std::cout << "NO";
}
return (0);
}
Maybe, if you share the test cases where things go wrong, it'll help me to spot the mistake in your code.
I dont know where I have a mistake
It work for the example but the result shows me "bad answer"
THE PROBLEM:
https://www.spoj.com/problems/SMPCIRC/
SMPCIRC - Two Circles
plane-geometry #basics
Given two circles: O1 with the center o1 = (xo1, yo1) and a radius r1
and O2 with the center o2 = (xo2, yo2) and radius r2, please compute
if O1 is inside O2 or if O2 is inside O1.
Input description First t < 1000, the number of test cases. In each of
the following t lines, 6 integers: xo1 yo1 r1 xo2 yo2 r2. Where 0 ≤
xo1, yo1, xo2, yo2 ≤ 10000 and 0 < r1, r2 ≤ 10000.
Output description For each test case print one character: I, if O1 is
inside O2 (or if O2 is inside O1), E, if O1 is internally tangent to
O2 (or if O2 is internally tangent to O1), O, in other cases.
Example
Input: 2 103 104 5 100 100 10 103 104 10 100 100 10
Output: E O
MY CODE:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int t;
cin>>t;
for(int i=0;i<t;i++)
{
double x1, y1, r1, x2, y2, r2, dl;
cin>>x1>>y1>>r1>>x2>>y2>>r2;
dl=sqrt(pow(x2-x1,2) + pow(y2-y1,2));
if(dl+r1==r2)
cout<<"E";
else if(dl+r2==r1)
cout<<"E";
else if (dl+r1<r2)
cout<<"I";
else if(dl+r2<r1)
cout<<"I";
else
cout<<"O";
}
return 0;
}
When using floating point types, a certain amount of numerical errors are to be expected. Sometimes this may be unacceptable for the kind of problem we are trying to solve.
The quote in OP's question, clearly state that the inputted variables are (emphasis mine)
6 integers: xo1 yo1 r1 xo2 yo2 r2. Where 0 ≤ xo1, yo1, xo2, yo2 ≤ 10000 and 0 < r1, r2 ≤ 10000.
Given the nature of the underlying mathematical problem, it's safe to use integer variables for the calculation too, applying just a bit of algebra:
#include <iostream>
constexpr long int square(long int x)
{
return x * x;
}
int main()
{
int t;
// Usually, the input is well defined in this kind of assignments
std::cin >> t;
for(int i=0; i < t; i++)
{
long int x1, y1, r1, x2, y2, r2;
std::cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
// Calculte the square of the distance
long int d2 = square(x2 - x1) + square(y2 - y1);
// Instead of d == r2 - r1, check if d^2 == (r2 - r1)^2
long int dr21 = square(r2 - r1);
if ( d2 > dr21 )
std::cout << "O\n";
else if ( d2 < dr21 )
std::cout << "I\n";
else // This is probably the least likely case
std::cout << "E\n";
}
return 0;
}
You shouldn't use == operator to compare two double values. Use
fabs(a - b) < eps instead of == operator. You can choose eps = 1e-7.
Also print a new line after each output.
I would like to ask a very short question, and it is as follows: in finding the cube root of a number (both neg. and pos.) in C++, how does one restrict the output to real solutions only?
I am currently writing a program to solve a cubic with Cardano's formula, and one of the intermediate variables I am using randomly outputs the complex and real cube roots - and I only need the real roots.
(E.g. in evaluating the cube root of -0.0127378, the three roots would be 0.11677095+0.202253218i, −0.2335419, 0.11677095−0.202253218i - I wish to ignore the complex ones for substitution into a later formula)
Thank you!
EDIT: Solved it! :) I created a signum function and tweaked the sign after taking the power of the absolute value of SPrime and TPrime, so now it carries forward only the real cube root.
/* ... */
#include <iostream>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cassert>
using namespace std;
int signum(std::complex<double> z)
{
if (z.real() < 0 || z.imag() < 0) return -1;
else if (z.real() >= 0 || z.imag() >= 0) return 1;
}
// POST: The function is intended to solve a cubic equation with coefficients a, b, c and d., such that
// ax^3 + bx^2 + cx + d = 0. If there exist infinitely many solutions, we output -1, i.e. if a=b=c=d=0
// (trivial solution).
void solve(std::complex<double> a, std::complex<double> b, std::complex<double> c, std::complex<double> d, std::complex<double>& x1, std::complex<double>& x2, std::complex<double>& x3)
{
complex<double> i = complex<double> (0, 1.0);
// Consider implementing Cardano's method for obtaining the solution of a degree 3 polynomial, as suggested
// We must hence define the discriminant D of such an equation through complex doubles Q and R
std::complex<double> Q;
Q = (3.0*a*c - pow(b, 2)) / (9.0*pow(a, 2));
cout << "Q=" << Q << endl;
std::complex<double> R;
R = (9.0*a*b*c - 27.0*d*pow(a, 2) - 2.0*pow(b, 3)) / (54.0*pow(a, 3));
cout << "R=" << R << endl;
std::complex<double> D;
D = pow(Q, 3) + pow(R, 2);
// Possible types of output for discriminant
if (abs(D) < 0.0)
{
cout << "The cubic has three distinct, real roots." << endl;
}
else if (abs(D) == 0.0)
{
cout << "The cubic has three real roots, at least two of which are equal." << endl;
}
else if (abs(D) > 0.0)
{
cout << "The cubic has one real root and two complex conjugate roots." << endl;
}
// Defining two further complex double variables S and T, which are required to obtain the final solution for x1, x2 and x3
std::complex<double> S;
std::complex<double> SPrime;
SPrime = R+sqrt(Q*Q*Q + R*R);
cout << "SPrime=" << SPrime << endl;
if (signum(SPrime) == -1)
{
S = (-1)*pow(abs(SPrime), 0.3333333333333);
}
else if (signum(SPrime) == 1)
{
S = pow(abs(SPrime), 0.3333333333333);
}
cout << "S=" << S << endl;
std::complex<double> T;
std::complex<double> TPrime;
TPrime = (R-sqrt(Q*Q*Q + R*R));
if (signum(TPrime) == -1)
{
T = (-1)*pow(abs(TPrime), 0.3333333333333);
}
else if (signum(TPrime) == 1)
{
T = pow(abs(TPrime), 0.3333333333333);
}
cout << "T=" << T << endl;
cout << "TPrime= " << TPrime << endl;
// Expressions for the solutions
x1 = S + T - (b/(3.0*a));
x2 = (-0.5)*(S + T) - (b/(3.0*a)) + (sqrt(3.0)*0.5)*(S - T)*i;
x3 = conj(x2);
if (abs(x1) < 0.000000000001)
{
x1 = 0;
}
}
// Driver code
int main ()
{
// Taking user input for a, b, c and d
std::complex<double> a, b, c, d, x1, x2, x3;
cout << "Please enter the coefficients of the polynomial in successive order." << endl;
cin >> a >> b >> c >> d;
solve (a, b, c, d, x1, x2, x3);
cout << x1 << ", " << x2 << ", " << x3 << "." << endl;
return 0;
}
The problem as you're stating it can be solved trivially (with real numbers the cubic root of -x is the opposite of the cubic root of x):
double cuberoot(double x) {
if (x < 0) {
return -pow(-x, 1.0/3.0);
} else if (x > 0) {
return pow(x, 1.0/3.0);
} else {
return 0;
}
}
If the input is instead in general complex z and you're looking for the "most real" (principal) cubic root the same reasoning can be applied using complex pow version to either z or -z depending on the sign of the real part:
std::complex<double> cuberoot(std::complex<double> z) {
if (z.real() < 0) {
return -pow(-z, 1.0/3.0);
} else {
return pow(z, 1.0/3.0);
}
}
Problems with your code:
As you allow complex coefficients, the discussion of the discriminant becomes slightly meaningless, it is only of value for real coefficients.
abs(D) is always non-negative. If D==0, then there is a double root, more can not be said in the case of complex coefficients.
You can avoid a lot of code by utilizing that S*T=-Q. One would have to care that the computation of u=T^3 returns the larger of the roots of 0==u^2 - 2*R*u - Q^3 or (u-R)^2 = D = R^2+Q^3
rtD = sqrt(D);
T = cuberoot( R + (abs(R+rtD)>=abs(R-rtD)) ? rtD : -rtD );
S = (abs(T)<epsilon) ? 0 : -Q/T;
Because of abs(R)<=abs(T)^3 and abs(D)<=abs(T)^6
one gets also abs(Q)<=2^(1/3)*abs(T)^2 resulting in
abs(S)=abs(Q/T) <= 2^(1/3)*abs(T)
For S=-Q/T to fail one would thus need a serious case
of extremely small floating point numbers in R, Q
and thus T. Quantitatively, for double even
the threshold epsilon=1e-150 should be safe.
On cube root variants:
For esthetic reasons one might want T as close to a coordinate axis as possible. A cube root function achieving this would be
std::complex<double> cuberoot(std::complex<double> z) {
double r=abs(z), phi=arg(z);
double k = round(2*phi/pi);
// closest multiple of pi/2
// an equivalent angle is (phi-k*pi/2) - k*3*pi/2
return std::polar( pow(r,1.0/3), (phi-k*pi/2)/3 - k*pi/2 );
}
so that abs(phi-k*pi/2)<=pi/4, and thus the angle to the next coordinate axis of the cube root is smaller than pi/12=15°. cuberoot(i) returns -i, cuberoot(-1) returns -1, a point at 60° returns a cube root at (60°-90°)/3-90°=-100°, etc.
How do I find the area of square or rectangle assuming user has entered some accurate points to form a square or rectangle.
I need to calculate the area inside the square class and rectangle class respectively.
I have 2 vector of coordinates, coordX and coordY.
My idea is when either or x or y has same value it will be a line and I can find the distance x2 but I'm not sure how to implement it in code.
double Square::computeArea() {
double area;
for (int x = 0; x < coordX.size; x++) {
for (int y = 0; y < coordY.size; y++) {
if (coordX[x] == coordY[y])
{
//....
}
}
}
return area;
}
This is how i populate my vector with user input
Square Square;
for ( int i = 1; i <= 4; i++) {
cout << "Please enter x-coordinate of pt " << i << ": ";
cin >> x;
Square.setXCoordinate(x);
cout << "Please enter y-coordinate of pt " << i << ": ";
cin >> y;
Square.setYCoordinate(y);
}
this is my mutator function in my class. Square inherit from ShapeTwoD
void ShapeTwoD::setXCoordinate(int x) {
coordX.push_back(x);
}
void ShapeTwoD::setYCoordinate(int y) {
coordY.push_back(y);
}
No need for square root.
Take two edges from one vertex, rotate one by 90°, take dot product.
double dx1 = coordX[3] - coordX[0];
double dy1 = coordY[3] - coordY[0];
double dx2 = coordX[1] - coordX[0];
double dy2 = coordY[1] - coordY[0];
double area = abs(dx1*dy2 - dy1*dx2)
As a bonus, this will calculate the correct area for all parallelograms, not just rectangles.
This assumes, the points are entered in clockwise or couter-clockwise order. If that's not the case, find out which point has the greatest distance to point[0] then discard it and use the other two instead of 1 and 3 above.
Assuming your coordinates are something like
// 3-----------2
// | |
// | |
// 0-----------1
Then you could do
#include <cmath>
double distance(double x1, double x2, double y1, double y2)
{
return std::sqrt(std::pow(x2 - x1, 2) + std::pow(y2 - y1, 2));
}
double Square::computeArea() const
{
double length = distance(coordX[0], coordX[1], coordY[0], coordY[1]);
double width = distance(coordX[0], coordX[3], coordY[0], coordY[3]);
return length * width;
}
This allows your rectangle to be at any arbitrary orientation, instead of x-y axis aligned. You just need to maintain a convention of the indexes of the corners, like in my example diagram.
I have a text file that include X,Y,Z coordinates of points. My aim is finding minimum and maximum points and write it another file. For this aim I write a distance function. The points that have maximum distance is minimum and maximum points. here is my code. It works but it does not calculate or write anything.
#include <iostream>
#include<fstream>
#include <math.h>
using namespace std;
double distance (float X1, float Y1, float Z1, float X2, float Y2, float Z2)
{
return sqrt(pow((X2-X1),2)+ pow((Y2-Y1),2)+pow((Z2-Z1),2));
}
int main ()
{
float x1, y1, z1,x2, y2,z2;
ifstream file("D:\\points.txt");
ofstream result ("D:\\result.txt");
double bigdistance=0;
if (file.is_open())
{
while (!file.eof())
{
file>>x1>>y1>>z1;
while (!file.eof())
{
file>>x2>>y2>>z2;
double d= distance (x1,y1,z1,x2,y2,z2);
if (bigdistance<d)
{
bigdistance=d;
result<<x1<<y1<<z1<<endl<<x2<<y2<<z2;
}
}
}
}
else cout <<"cannot open file";
system ("PAUSE");
return 0;
}
A couple of suggestions:
while (file >> x1 >> y1 >> z1 >> x2 >> y2 >> z2) {
}
will read your input and stop if any of the reads failed.
You will want to read the entire input and store it in a vector of points, or similar. Then, you can use two nested loops to iterate over each pair of points. Right now, your programs assumes that the input file contains all pairs. That is, each point is read multiple times form the input, in the inner loop.
There are also algorithms that are faster than quadratic, and you might need those if you have more than a couple thousand input points. See for example this StackOverflow question.
#include <iostream>
#include<fstream>
#include <math.h>
using namespace std;
enter code here`{
for (int i = 1; !f1.eof(); i++)
{
int x1, y1, x2, y2, x3, y3, x4, y4);
read(f1, x1, y1, x3, y3);
x2 = x3;
y2 = y1;
x4 = x1;
y4 = y3;
if (y4 > y1)
{
a = y1 - y4;
}
else
a = y4 - y1;
if (x4 > x3)
{
b = x4 - x3;
}
else
b = x3 - x4;
}
}