比赛链接
D.雪色光晕
题目描述
给出两个初始点,一个点动 n 次,另外一个点不动,给出动点的方向向量 (dx,dy),求动点和静点的最短距离
输入描述:
第一行是一个正整数 n。
第二行是四个整数 x0、 y0、x 和 y ,用空格隔开。用来表示动点和静点的初始坐标。
接下来的n行,每行输入两个整数 xi 和 yi,用来表示方向向量坐标。
数据范围:
1≤n≤200000
109≤x,y,xi,yi≤109
输出描述:
最近的距离。如果你的答案和正确答案的相对误差不超过 10−7,则认为答案正确。
示例1
输入
输出
示例2
输入
输出
示例3
输入
输出
解题思路
计算几何
点到直线的距离公式:
设直线 L 的方程为Ax+By+C=0,点 P 的坐标为(x0,y0),则点 P 到直线 L 的距离为:Ax0+By0+CA2+B2
同理可知,当P(x0,y0),直线L的解析式为y=kx+b时,则点P到直线L的距离为:|kx0−y0+b|√k2+1
求出静点到 n 个线段的最小值即可
代码
#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
double x,y,xx,yy;
int n;
double dis(double x,double y,double xx,double yy)
{
return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy));
}
double f(double dx,double dy)
{
double xe=x+dx,ye=y+dy;
double res=min(dis(x,y,xx,yy),dis(xe,ye,xx,yy));
double k=dy/dx,b=y-k*x,bb=yy+1/k*xx;
double xj=(bb-k*b)/(k*k+1);
if(xj>=min(x,xe)&&xj<=max(x,xe))res=min(res,fabs(k*xx-yy+b)/sqrt(k*k+1));
return res;
}
int main()
{
scanf("%d",&n);
scanf("%lf%lf%lf%lf",&x,&y,&xx,&yy);
double res=dis(x,y,xx,yy);
while(n--)
{
double dx,dy;
scanf("%lf%lf",&dx,&dy);
res=min(res,f(dx,dy));
x+=dx,y+=dy;
}
printf("%lf",res);
return 0;
}
G.子序列权值乘积
题目描述
小红定义一个数组的权值为该数组的最大值乘以最小值。例如数组 [4,1,3] 的权值是 4∗1=4。
小红拿到了一个数组。她想知道,这个数组的所有 非空子序列 的权值的乘积是多少?由于该数过大,请对1000000007取模。
子序列的定义:对于一个数组,删除其中某些数之后(也可以不删)得到的数组。子序列中的数的相对顺序必须和原数组中的顺序相同。
例如:数组 [1,3,2] 的非空子序列有 [1][3][2][1,3][1,2][3,2][1,3,2] 共7个。
输入描述:
第一行输入一个正整数 n ,代表数组的长度。
第二行输入 n 个正整数 ai,代表小红拿到的数组。
数据范围:
1≤n≤200000
1≤ai≤109
输出描述:
数组所有子序列的权值的乘积。答案对1000000007取模。
示例1
输入
输出
说明
对于子序列 [2,3] ,其权值为 3∗2=6。
对于子序列 [2] ,其权值为 2∗2=4。
对于子序列 [3] ,其权值为 3∗3=9。
因此所有非空子序列的权值乘积为: $6 * 4 * 9 = 216¥
示例2
输入
输出
解题思路
欧拉降幂:若正整数 a,n 互质,则对于任何正整数 b,有 ab≡abmodφ(n)(modn)
由于是子序列,我们考虑每个值对答案的贡献,将数组排序并不会影响答案,对某个值 ai,其作为最小值时,后面的数即更大的数不能取否则与最小值矛盾,前面的数可以任取,即有 i−1 个数可取可不取,共 2i−1 种方案,同理,后面 n−i 个数有 2n−i 种方案,共 2i−1+2n−i 种方案,其对答案的贡献为 a2i−1+2n−ii,单单算的话由于指数过大会超时,可以欧拉降幂: a2i−1+2n−ii=a(2i−1+2n−i)modφ(1e9+7)i
- 时间复杂度:O(n(logn+log(1e9+7)))
代码
I.爆炸的符卡洋洋洒洒
题目描述
给出 n 个物品体积 ai 和价值 bi,各物品最多只能选择一次,要求选出的物品的体积为 k 的倍数,求最大价值
输入描述:
第一行输入两个正整数 n 和 k ,用空格隔开。
接下来的 n 行,每行输入两个正整数 ai 和 bi,用空格隔开。
数据范围:
1≤n,k≤1000
1≤ai,bi≤109
输出描述:
体积无法形成倍数关系,则输出−1。
否则输出最大价值。
示例1
输入
输出
示例2
输入
输出
示例3
输入
输出
解题思路
01背包变形
背包体积过大,但是 k 较小,可将体积对 k 取模,将体积转化为模,将要求的体积转化为模为 0,即:
- 状态表示:f[i][j] 表示前 i 个物品体积对 k 取模为 j 时的最大价值
- 状态计算:f[i][j]=max(f[i−1][j],f[i−1][(j−v[i]%k+k)%k]+w[i])
注意:初始化要尽可能小,表示取不到,f[0][0] 表示 0 个物品价值为 0
代码
J.区间合数的最小公倍数
题目描述
给定一个区间 [l,r],求其中所有合数的最小公倍数
输入描述:
两个正整数 l 和 r ,用空格隔开。
数据范围:1≤l≤r≤30000
输出描述:
若区间 [l,r] 中没有任何合数,则输出−1。
否则输出区间 [l,r] 所有合数的最小公倍数,答案对1000000007取模。
示例1
输入
输出
说明
区间 [2,3] 的两个数 2 和 3 都是素数,不是合数。
示例2
输入
输出
说明
区间[4,6]中有三个数:4、5、6,其中 5 是素数, 4 和 6 是合数,它们的最小公倍数是12。
示例3
输入
输出
解题思路
数学:求取多个数的最小公倍数,即将所有数分解质因数,统计每个素数出现的最高次幂,其乘积即为所求
例:a=23∗35∗51,b=24∗31∗52,那么它们的最小公倍数就是 24∗35∗52
直接欧拉筛求素数,剩余的合数求最小公倍数即可
代码
__EOF__
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!