牛客竞赛21842 正方形检测

第一次提交:(过了95.74%)

#include <bits/stdc++.h>
using namespace std;
struct point
{
  double x;
  double y;
} p[5];
double dis(int x1, int y1, int x2, int y2)
{
  double c = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  return c;
}
bool cmp(point p1, point p2)
{ // 按x升序排列,若x相同则y升序
  if (p1.x < p2.x)
    return true;
  else if (p1.x == p2.x && p1.y < p2.y)
    return true;
  else
    return false;
}
int main()
{
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].x;
  }
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].y;
  }
  // 正方形判断条件:四边相等 + 一个角为直角
  sort(p, p + 4, cmp); // 排序后,四边即可精确求解(不用算对角线)
  // 计算四条边大小
  double d1 = dis(p[0].x, p[0].y, p[1].x, p[1].y);
  double d2 = dis(p[0].x, p[0].y, p[2].x, p[2].y);
  double d3 = dis(p[1].x, p[1].y, p[3].x, p[3].y);
  double d4 = dis(p[2].x, p[2].y, p[3].x, p[3].y);
  int flag = 0;
  if (d1 == d2 && d2 == d3 && d3 == d4) // 若相同则“四边相等”成立
  {                                     // 再判断是否有一个角为直角:k1*k2==-1 or 两线分别与xy轴平行
    if (p[0].x == p[1].x && p[0].y == p[2].y)
    {
      cout << "It's a square";
      flag = 1;
    }
    else if ((p[1].y - p[0].y) / (p[1].x - p[0].x) * (p[2].y - p[0].y) / (p[2].x - p[0].x) == -1)
    {
      cout << "It's a square";
      flag = 1;
    }
  }

  if (flag == 0)
  {
    cout << "Not a square";
  }
}

第二次提交:(过了100%)把条件k1*k2=-1改成k1=-1/k2即可

#include <bits/stdc++.h>
using namespace std;
struct point
{
  double x;
  double y;
} p[5];
double dis(int x1, int y1, int x2, int y2)
{
  double c = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  return c;
}
bool cmp(point p1, point p2)
{ // 按x升序排列,若x相同则y升序
  if (p1.x < p2.x)
    return true;
  else if (p1.x == p2.x && p1.y <= p2.y)
    return true;
  else
    return false;
}
int main()
{
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].x;
  }
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].y;
  }
  // 正方形判断条件:四边相等 + 一个角为直角
  sort(p, p + 4, cmp); // 排序后,四边即可精确求解(不用算对角线)
  // 计算四条边大小
  double d1 = dis(p[0].x, p[0].y, p[1].x, p[1].y);
  double d2 = dis(p[0].x, p[0].y, p[2].x, p[2].y);
  double d3 = dis(p[1].x, p[1].y, p[3].x, p[3].y);
  double d4 = dis(p[2].x, p[2].y, p[3].x, p[3].y);
  int flag = 0;
  if (d1 == d2 && d2 == d3 && d3 == d4) // 若相同则“四边相等”成立
  {                                     // 再判断是否有一个角为直角:k1*k2==-1 or 两线分别与xy轴平行
    if (p[0].x == p[1].x && p[0].y == p[2].y)
    {
      cout << "It's a square";
      flag = 1;
    }
    // else if ((p[1].y - p[0].y) / (p[1].x - p[0].x) * (p[2].y - p[0].y) / (p[2].x - p[0].x) == -1)
    else if ((p[1].y - p[0].y) / (p[1].x - p[0].x) == -(p[2].x - p[0].x) / (p[2].y - p[0].y)) // 改这条
    {
      cout << "It's a square";
      flag = 1;
    }
  }

  if (flag == 0)
  {
    cout << "Not a square";
  }
}

此题我认为难点是确定四点的位置关系。排序后,四点的位置就确定了。

ps:不排序也可,判断四边是否相等时可以计算六条边(包括四条边和两条对角线),之后判断是否满足四条边相等且长边=短边*√2

代码:

第一次:(过了85.11%,原因是开方后精度问题)

#include <bits/stdc++.h>
using namespace std;
double d[7];
struct point
{
  double x;
  double y;
} p[5];
double dis(int x1, int y1, int x2, int y2)
{
  double c = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
  return c;
}
bool cmp(point p1, point p2)
{ // 按x升序排列,若x相同则y升序
  if (p1.x < p2.x)
    return true;
  else if (p1.x == p2.x && p1.y <= p2.y)
    return true;
  else
    return false;
}
int main()
{
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].x;
  }
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].y;
  }
  // 计算六条边大小
  d[1] = dis(p[0].x, p[0].y, p[1].x, p[1].y);
  d[2] = dis(p[0].x, p[0].y, p[2].x, p[2].y);
  d[3] = dis(p[0].x, p[0].y, p[3].x, p[3].y);
  d[4] = dis(p[1].x, p[1].y, p[2].x, p[2].y);
  d[5] = dis(p[1].x, p[1].y, p[3].x, p[3].y);
  d[6] = dis(p[2].x, p[2].y, p[3].x, p[3].y);
  sort(d + 1, d + 7); // 排序
  int flag = 0;
  if (d[1] == d[2] && d[2] == d[3] && d[3] == d[4] && d[5]  == sqrt(2) * d[1] && d[5] == d[6])
  {
    cout << "It's a square";
    flag = 1;
  }
  if (flag == 0)
  {
    cout << "Not a square";
  }
}

第二次提交:(过了100%,这里没有用sqrt,而是直接保存距离的平方,把a,a,√2a的关系转化为a²,a²,2a²的关系,之后判断边与对角线的关系,进而判断是否是直角)

#include <bits/stdc++.h>
using namespace std;
double d[7];
struct point
{
  double x;
  double y;
} p[5];
double dis(int x1, int y1, int x2, int y2)
{
  double c = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  return c;
}
bool cmp(point p1, point p2)
{ // 按x升序排列,若x相同则y升序
  if (p1.x < p2.x)
    return true;
  else if (p1.x == p2.x && p1.y <= p2.y)
    return true;
  else
    return false;
}
int main()
{
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].x;
  }
  for (int i = 0; i < 4; i++)
  {
    cin >> p[i].y;
  }
  // 计算六条边大小
  d[1] = dis(p[0].x, p[0].y, p[1].x, p[1].y);
  d[2] = dis(p[0].x, p[0].y, p[2].x, p[2].y);
  d[3] = dis(p[0].x, p[0].y, p[3].x, p[3].y);
  d[4] = dis(p[1].x, p[1].y, p[2].x, p[2].y);
  d[5] = dis(p[1].x, p[1].y, p[3].x, p[3].y);
  d[6] = dis(p[2].x, p[2].y, p[3].x, p[3].y);
  sort(d + 1, d + 7); // 排序
  int flag = 0;
  if (d[1] == d[2] && d[2] == d[3] && d[3] == d[4] && d[5]  == 2 * d[1] && d[5] == d[6])
  {
    cout << "It's a square";
    flag = 1;
  }
  if (flag == 0)
  {
    cout << "Not a square";
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值