专栏文章
题解:P10907 [蓝桥杯 2024 国 B] 蚂蚁开会
P10907题解参与者 4已保存评论 3
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @min228i2
- 此快照首次捕获于
- 2025/12/01 19:17 3 个月前
- 此快照最后确认于
- 2025/12/01 19:17 3 个月前
一道数学和哈希表的结合。
要在所有整数交点上建会议中心,直接求出这么多线段的交点再判断是否为整点显然不优,正难则反,直接把所有线段上的整点存到一个数组里,判断这个点的出现次数,如果大于等于 ,就是两条或多条线段的交点。
自然想到使用哈希表进行维护。
CPPconst int t = 2e6+7;
struct hash_map{ //哈希表
struct data{
long long u;
int v,nex;
};
data e[t << 1];
int h[t],cnt;
int hash(long long u){
return (u % t + t)% t;
}
int& operator[](long long u){
int hu = hash(u);
for(int i = h[hu];i;i = e[i].nex){
if(e[i].u == u) return e[i].v;
}
e[++cnt]=data{u, 0, h[hu]};
h[hu] = cnt;
return e[cnt].v;
}
hash_map(){
cnt = 0;
memset(h, 0, sizeof(h));
}
};
创建了一个哈希表,并保证对于所有没有存过值的键,它们的初始值都为 。
那么如何求出每条线段上的整点?
这里需要一点数学方法。可以把两点组成的线段看为一个向量,那么只需求出它的单位向量,再将这个向量分解到 x 轴和 y 轴上。这样,我们每走一个单位步长,就可以到一个新的整点。代码如下:
CPPint delx = c-a;
int dely = d-b;
int k = __gcd(abs(delx), abs(dely));
int xs = delx/k; //遍历线段上的所有整点
int ys = dely/k;
那么后面的步骤显然,将每个点的横坐标与纵坐标拟合成一个哈希值存入即可。
接下来遍历哈希表,找到出现次数大于等于 的点的个数。
完整代码如下:
CPP#include<bits/stdc++.h>
using namespace std;
const int t = 2e6+7;
struct hash_map{//哈希表
struct data{
long long u;
int v,nex;
};
data e[t << 1];
int h[t],cnt;
int hash(long long u){
return (u % t + t)% t;
}
int& operator[](long long u){
int hu = hash(u);
for(int i = h[hu];i;i = e[i].nex){
if(e[i].u == u) return e[i].v;
}
if(cnt >= (t << 1) -1){//避免数字过大越界
static int q = 0;
return q;
}
e[++cnt] = data{u, 0, h[hu]};
h[hu] = cnt;
return e[cnt].v;
}
hash_map(){
cnt=0;
memset(h, 0, sizeof(h));
}
};
hash_map nump;
int n,a,b,c,d,cnt;
int main() {
cin>>n;
for(int i = 0;i < n;i++){
cin>>a>>b>>c>>d;
int delx = c-a;
int dely = d-b;
int k = __gcd(abs(delx), abs(dely));
int xs = delx/k;//遍历线段上的所有整点
int ys = dely/k;
for(int j = 0;j <= k;j++){
long long x = a+j*xs;
long long y = b+j*ys;
const long long m = 1e9+7;
long long r = x * m + y;//组合坐标作为哈希表的键
nump[r]++;
}
}
for(int i = 0;i < t;i++){//统计重复出现的点
for(int j = nump.h[i];j;j = nump.e[j].nex){
nump.e[j].v >= 2?cnt++:cnt;
}
}
cout<<cnt<<endl;
return 0;
}
相关推荐
评论
共 3 条评论,欢迎与作者交流。
正在加载评论...