牛客竞赛21842 正方形检测

简介: 牛客竞赛21842 正方形检测

533f2719e9e046318ab97a0314f339e5.jpg

26df12d490404137bf890ad5c04b022d.jpg

第一次提交:(过了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";
  }
}


ae0fe5b190244428bcebb48cbc1afa68.jpg

第二次提交:(过了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";
  }
}


2de5fe5a04954897b56705a4c0b7b570.jpg

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

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";
  }
}


3d779d9393e44d39829be8c06df24819.jpg


第二次提交:(过了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";
  }
}


相关文章
|
17天前
|
存储 Python 容器
每日一题 2013. 检测正方形
每日一题 2013. 检测正方形
|
3天前
|
机器学习/深度学习 存储
力扣经典150题第三十六题:旋转图像
力扣经典150题第三十六题:旋转图像
4 0
|
3天前
|
存储 算法 测试技术
力扣经典150题第五十题:用最少数量的箭引爆气球
力扣经典150题第五十题:用最少数量的箭引爆气球
6 0
|
11天前
|
C++
【洛谷 P1042】[NOIP2003 普及组] 乒乓球 题解(模拟+向量)
`NOIP2003`普及组编程题:乒乓球比赛模拟。给定一系列球赛记录(WL序列),程序需按11分和21分制分析比分。输入含多个字符串,含W(华华得分)、L(对手得分)和E(结束标记)。输出每局比分,分制间空行间隔。样例:`WWWWWW...` → `11:0\n11:0\n1:1`(11分制)和`21:0\n2:1`(21分制)。代码使用C++,逐字符读取,当分差≥2且得分≥x时输出比分。
4 0
|
2月前
【编程题-错题集】kotori和气球(组合数学)
【编程题-错题集】kotori和气球(组合数学)
|
8月前
|
算法 测试技术 容器
代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
代码随想录算法训练营第四十二天 | LeetCode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
33 1
|
8月前
|
算法 Java
代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
45 0
|
10月前
|
C++
蓝桥杯 2240. 买钢笔和铅笔的方案数c++解法
蓝桥杯 2240. 买钢笔和铅笔的方案数c++解法
94 0
|
11月前
|
机器学习/深度学习 决策智能 计算机视觉
对硬币、销钉、大米进行图像分割(附代码)
对硬币、销钉、大米进行图像分割(附代码)
|
算法
算法创作|纸牌三角形
算法创作|纸牌三角形
52 0