当前位置: 首页 > news >正文

[蓝桥杯 2024 国 B] 蚂蚁开会

问题描述

二维平面上有 n 只蚂蚁,每只蚂蚁有一条线段作为活动范围,第 i 只蚂蚁的活动范围的两个端点为 (uix,uiy),(vix,viy)。现在蚂蚁们考虑在这些线段的交点处设置会议中心。为了尽可能节省经费,它们决定只在所有交点为整点的地方设置会议中心,请问需要设置多少个会议中心?

输入格式

输入共 n+1 行。第一行为一个正整数 n。后面 n 行,每行 4 个由空格分开的整数表示 uix,uiy,vix,viy​。

输出格式

输出共 1 行,一个整数表示答案。

样例输入

4
0 0 4 4
0 4 4 0
2 0 0 4
2 1 2 3

样例输出

2

样例说明

所有线段之间共有 3 个不同的交点:(0,4),(4,3),(2,2),其中整点有 2 个:(0,4),(2,2)。

评测用例规模与约定

对于 20% 的评测用例,保证 0≤uix,uiy,vix,viy≤100。

对于 100% 的评测用例,保证 n≤500,0≤uix,uiy,vix,viy≤10000,保证任意蚂蚁的活动范围不会退化成一个点,不保证任意两条线段之间交点数量有限。

解题思路:

问需要设置多少个会议中心,即找出所有交点为整点的地方。

整点,顾名思义,横纵坐标为整数的点,样例(4,3)这个点挺迷惑的,直接按题目意思来即可。

要找出这些点,我们可以通过找到每条线段上的整点,再对这些整点出现的次数进行统计,次数>=2的即为交点,也就是设置会议中心的点。

要找到每条线段上的整点,涉及数学知识,为以下式子:

//p1,p2为两个端点,p1.x为一个端点的横坐标,p1.y为纵坐标
int dx=p2.x-p1.x;//dx和dy表示从p1到p2在x和y方向上的变化量
int dy=p2.y-p1.y;
int gcd=Math.abs(gcd(dx,dy));//gcd是两个数的最大公约数,决定了线段上整数点的分布密度
//例如:如果dx=3和dy=6,则gcd=3,说明线段上有3+1=4个整数点
//这些点的间隔为(dx/gcd, dy/gcd) = (1, 2)
int stepX=dx/gcd;//stepX和stepY表示从一个整数点到下一个整数点的坐标变化量
int stepY=dy/gcd;
int step=gcd;//代表有step个整数点

 代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;public class Main {static class Point{int x,y;public Point(int x,int y) {this.x=x;this.y=y;}// 重写hashCode和equals方法,确保HashMap能正确识别相同坐标的点//将自定义对象(如Point类)用作HashMap或HashSet的键时,必须重写hashCode()和equals()方法@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Point point = (Point) o;return x == point.x && y == point.y;}@Overridepublic int hashCode() {return java.util.Objects.hash(x, y);}}public static void main(String[] args) {Scanner sc=new Scanner(System.in);int n=sc.nextInt();Map<Point,Integer> pointCount=new HashMap<>();for(int i=0;i<n;i++) {int x1=sc.nextInt();int y1=sc.nextInt();int x2=sc.nextInt();int y2=sc.nextInt();Point p1=new Point(x1,y1);Point p2=new Point(x2,y2);List<Point> points=new ArrayList<>();points=getPoints(p1,p2);//计算两个端点p1,p2之间存在多少整点for(Point p:points) {pointCount.put(p,pointCount.getOrDefault(p, 0)+1);//对每个整点出现的次数进行计数}}//寻找出现次数>=2的整点,计数int count=0;for(Map.Entry<Point, Integer> entry:pointCount.entrySet()) {if(entry.getValue()>=2) {count++;}}System.out.println(count);}private static List<Point> getPoints(Point p1,Point p2){List<Point> points=new ArrayList<>();int dx=p2.x-p1.x;int dy=p2.y-p1.y;int gcd=Math.abs(gcd(dx,dy));int stepX=dx/gcd;int stepY=dy/gcd;int step=gcd;for(int i=0;i<=step;i++) {//遍历寻找所有整点int x=p1.x+i*stepX;int y=p1.y+i*stepY;points.add(new Point(x,y));//存储每个整点}return points;}private static int gcd(int a,int b) {return b==0?a:gcd(b,a%b);}}

相关文章:

  • mq安装新版-3.13.7的安装
  • LLMs 系列科普文(14)
  • 由汇编代码确定switch语句
  • Digital IC Design Flow
  • C++修炼:C++11(三)
  • Java并发编程实战 Day 14:并发编程最佳实践
  • 华为OD机考-内存冷热标记-多条件排序
  • 强化学习入门:交叉熵方法数学推导
  • 把二级域名绑定的wordpress网站的指定页面
  • 计组_导学
  • java复习 05
  • wpf在image控件上快速显示内存图像
  • 手动给中文分词和 直接用神经网络RNN做有什么区别
  • 如何利用 OpenCV 进行实时图像处理与对象检测
  • Python实例题:Python计算概率论
  • python打卡day48@浙大疏锦行
  • MCP(Model Context Protocol)模型上下文协议 番外篇 2025-03-26 更新
  • 鸿蒙学习笔记01
  • 第三章支线三 ·异步幻境 · 时间之缝的挑战
  • Redis 知识点一
  • 创意集团网站建设/seo快速排名软件平台
  • perl网站建设/搜索引擎优化是什么
  • 泰和网站制作/seo提升排名
  • 宁乡建设局网站/站长工具seo推广秒收录
  • bl做视频网站/聊城今日头条最新
  • 网站建设企业实践日志/岳阳seo公司