A - Obesity
题目描述
用下面的公式计算出的数值叫做 \\mathrm{BMI}\[\\mathrm{kg}/\\mathrm{m}\^2\] 。
- \\text{Weight}\[\\mathrm{kg}\] \\div \\text{Height}\[\\mathrm{m}\] \\div \\text{Height}\[\\mathrm{m}\]
在日本, \\mathrm{BMI} 大于或等于 25 \\; \\mathrm{kg}/\\mathrm{m}\^2 的人被视为肥胖。
请判断身高 H\[\\mathrm{cm}\] 、体重 W\[\\mathrm{kg}\] 的人在日本是否属于肥胖。
解题思路
A题不讲了。脑残题。
完整代码
#include<bits/stdc++.h>
#define fr1(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define fr2(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define fv(i,p) for(auto (i):(p))
#define ll long long
#define ull unsigned ll
#define pii pair<int,int>
#define pll pair<ll,ll>
#define _1st first
#define _2nd second
#define elif else if
#define debug cout<<endl<<"-------------------------------------------------------------"<<endl
using namespace std;
int h,w;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
cin>>h>>w;
if(400*w>=h*h){
cout<<"Yes";
}else{
cout<<"No";
}
return 0;
}
B - Keep the Change
题目描述
高桥在 N 家商店购物。最初,他有 10000 日元。
在 i th商店,他购买了价值 A_i 日元的商品,支付了 B_i 日元。这里, A_i \\leq B_i 成立。如果 S_i = keep ,他没有收到零钱;如果 S_i = take , A_i \\leq B_i 成立 ,他收到了零钱。
求与他在每家店都收到零钱的情况相比,他损失了多少钱。准确地说:
设 X 日元是高桥的最终金额,并且让 Y 日元成为高桥在每家店都收到零钱的情况下的最终金额。
求出 Y - X .
解题思路
最脑残的一次B题。
完整代码
#include<bits/stdc++.h>
#define fr1(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define fr2(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define fv(i,p) for(auto (i):(p))
#define ll long long
#define ull unsigned ll
#define pii pair<int,int>
#define pll pair<ll,ll>
#define _1st first
#define _2nd second
#define elif else if
#define debug cout<<endl<<"-------------------------------------------------------------"<<endl
using namespace std;
int n,ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
cin>>n;
fr1(i,1,n){
int a,b;
string s;
cin>>a>>b>>s;
if(s=="keep")ans+=b-a;
}
cout<<ans;
return 0;
}
C - Adjacent Sums(简单版)
题目描述
C 题的题目描述与E题相同。只有加粗的数据范围不同。
给你一个整数序列 A=(A_1,A_2,\\dots,A_N),B=(B_1,B_2,\\dots,B_{N-1}) ,它由介于 0 与 M-1 之间的整数组成。 A 和 B 的长度分别为 N 和 N-1 。
您可以对 A 执行以下操作任意多次。
- 选择带有 1 \\leq i \\leq N 的整数 i ,将 1 加到 A_i 中。
求满足以下条件所需的最少运算次数。
可以证明,在本题的限制条件下,该条件总是可以满足的。
- 对于 i=1,2,\\dots,N-1 来说, A_i+A_{i+1} 除以 M 的余数等于 B_i 。
数据范围
- 2 \\leq N \\leq 2 \\times 10\^5
- M=2
- 0 \\leq A_i \\leq M-1
- 0 \\leq B_i \\leq M-1
- 所有输入值均为整数。
解题思路
数学转化(核心,M=2,模 2 等价异或)
模 2 加法等价于按位异或:
\((P+Q) \bmod 2 = P \oplus Q\) 把约束拆开:
\((A_i+x_i) \oplus (A_{i+1}+x_{i+1}) = B_i\) 移项变形(异或等式两边同时异或同一个数等式不变):
\(x_{i+1} = B_i \oplus A_i \oplus x_i \oplus A_{i+1}\) .
关键结论:整个序列 \(x_1,x_2,\dots,x_N\) 完全由 \(x_1\) 决定
- 若确定 \(x_1\),用上面公式能依次算出 \(x_2,x_3,\dots,x_N\);
- 因为 \(M=2\),\(x_1\) 在模 2 下只有两种可能:0 或 1;
- 只需要枚举 \(x_1=0\)、\(x_1=1\) 两种情况,分别算出全套 x 数组的总代价 \(\sum x_i\),取最小值就是答案。
代价说明
为什么代价直接累加 \(x_i\)? \(x_i\) 是第 i 个元素一共加了多少次 1,每加 1 算一次操作,总操作次数就是所有 \(x_i\) 相加,和题目定义完全一致。
完整代码
#include<bits/stdc++.h>
#define fr1(i,a,b) for(int(i)=(a);(i)<=(b);(i)++)
#define fr2(i,a,b) for(int(i)=(a);(i)>=(b);(i)--)
#define fv(i,p) for(auto (i):(p))
#define ll long long
#define ull unsigned ll
#define pii pair<int,int>
#define pll pair<ll,ll>
#define _1st first
#define _2nd second
#define elif else if
#define debug cout<<endl<<"-------------------------------------------------------------"<<endl
using namespace std;
int n,m;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
cin>>n>>m;
vector<int>a(N+1),b(N);
fr1(i,1,N)cin>>a[i];
fr1(i,1,N-1)cin>>b[i];
ll ans=LLONG_MAX;
fr1(start,0,1){
vector<int>x(n+1);
x[1]=start;
ll cost=x[1];
fr1(i,1,n-1){
x[i+1]=b[i]^a[i]^x[i]^a[i+1];
cost+=x[i+1];
}
ans=min(ans,cost);
}
cout<<ans<<endl;
return 0;
}
D - Concentric Circles
题目描述
在 xy \ 平面上是否存在满足以下所有条件的两个圆 C_1 和 C_2 ?这里, C_1 和 C_2 可能重合。
-
两个不同的点 (P_x, P_y) 和 (Q_x, Q_y) 位于 C_1 的圆周上。
-
两个不同的点 (R_x, R_y) 和 (S_x, S_y) 位于 C_2 的圆周上。
-
C_1 与 C_2 具有相同的圆心。
给你 T 个测试用例,请逐一求解。
数据范围
- 1 \\leq T \\leq 5 \\times 10\^4
- -10\^9 \\leq P_x,P_y,Q_x,Q_y,R_x,R_y,S_x,S_y \\leq 10\^9
- (P_x, P_y) \\neq (Q_x, Q_y)
- (R_x, R_y) \\neq (S_x, S_y)
- 所有输入值均为整数。
解题思路
一、几何前置结论:两点确定圆心的约束
若一个圆同时过两个不同点 \(A,B\),设圆心为 \(O(x_0,y_0)\),则:
\(|OA|^2 = |OB|^2\) 展开距离平方并化简:
\((x_0-A_x)^2+(y_0-A_y)^2 = (x_0-B_x)^2+(y_0-B_y)^2\) 消去 \(x_0^2,y_0^2\),整理得到一条直线方程:
\(2(B_x-A_x)x_0 + 2(B_y-A_y)y_0 = B_x^2+B_y^2 - A_x^2-A_y^2\) 这条直线就是线段 AB 的垂直平分线。
关键:所有能作为 "过 \(A,B\) 的圆的圆心" 的点,全部落在 AB 的垂直平分线上。
设:
- \(L_1\):PQ 的垂直平分线(所有合法 \(C_1\) 圆心集合)
- \(L_2\):RS 的垂直平分线(所有合法 \(C_2\) 圆心集合)
题目等价转化为:直线 \(L_1\) 和 \(L_2\) 是否存在交点。
- 若存在交点 O:以 O 为圆心,分别取 \(|OP|\)、\(|OR|\) 为半径作同心圆,满足全部条件,输出 Yes;
- 若不存在交点(两直线平行且不重合):没有公共圆心,输出 No。
二、分两类讨论 \(L_1\) 与 \(L_2\) 的位置关系
两条直线只有两种位置:
- 不平行(相交);
- 平行(要么完全重合,要么无交点)。
情况 1:\(L_1\) 与 \(L_2\) 不平行 → 一定有交点 → 答案 Yes
两条直线不平行等价于:线段 PQ、RS 本身不平行。 线段平行判定:取向量 \(\overrightarrow{PQ}=(Q_x-P_x,Q_y-P_y)\),\(\overrightarrow{RS}=(S_x-R_x,S_y-R_y)\)。 二维向量平行充要条件:叉积为 0
\(\text{cross} = v_{1x} \cdot v_{2y} - v_{1y} \cdot v_{2x}\)
-
\(\text{cross} \neq 0\):向量不平行 → \(L_1,L_2\) 不平行,必有交点,直接 Yes。
ll v1x=Qx-Px,v1y=Qy-Py;
ll v2x=Sx-Rx,v2y=Sy-Ry;
ll cross=v1xv2y-v1yv2x;
if(cross!=0){cout<<"Yes\n";}
情况 2:\(\text{cross}=0\),即 \(PQ \parallel RS\),此时 \(L_1 \parallel L_2\)
平行线分两种:重合 / 分离。 只有两条垂直平分线完全重合时,才存在无穷多公共圆心,输出 Yes;否则无公共圆心,输出 No。
那么,如何判断两条垂直平分线 \(L_1,L_2\) 是否重合?
\(L_1\) 是 PQ 中垂线,\(L_2\) 是 RS 中垂线,且 \(PQ \parallel RS\)。 取 RS 上任意一点(如 R),判断 R 是否在 \(L_1\) 上;再取 S 判断是否在 \(L_1\) 上。 若 \(R,S\) 都在 PQ 的中垂线上 → \(L_1,L_2\) 完全重合。
R 在 PQ 中垂线的充要条件:\(|RP|^2 = |RQ|^2\) 展开距离平方:
\((R_x-P_x)^2+(R_y-P_y)^2 = (R_x-Q_x)^2+(R_y-Q_y)^2\) 移项变形,等价于:
\((2R_x-P_x-Q_x)^2 + (2R_y-P_y-Q_y)^2 = 0\) 同理,S 在 PQ 中垂线等价于:
\((2S_x-P_x-Q_x)^2 + (2S_y-P_y-Q_y)^2 = 0\)
比较平方和是否相等:
ll lhs=(2*Rx-Px-Qx)*(2*Rx-Px-Qx)+(2*Ry-Py-Qy)*(2*Ry-Py-Qy);
ll rhs=(2*Sx-Px-Qx)*(2*Sx-Px-Qx)+(2*Sy-Py-Qy)*(2*Sy-Py-Qy);
if(lhs==rhs) cout<<"Yes\n";
else cout<<"No\n";
- \(lhs=rhs\):\(R、S\) 都在 PQ 中垂线上 → \(L_1=L_2\),无数公共圆心,Yes;
- \(lhs≠rhs\):\(R、S\) 不在同一条中垂线,两平行线分离,无公共圆心,No。
整体流程概括
对每组测试用例:
- 求向量 \(\overrightarrow{PQ},\overrightarrow{RS}\),计算叉积;
- 叉积≠0 → 两中垂线相交 → Yes;
- 叉积 = 0(线段平行):
- 计算 R 到 PQ 中点距离平方、S 到 PQ 中点距离平方;
- 两值相等 → 中垂线重合,存在公共圆心 → Yes;
- 两值不等 → 中垂线平行分离,无公共圆心 → No。
完整代码
#include<bits/stdc++.h>
#define fr1(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define fr2(i,a,b) for(int (i)=(a);(i)>=(b);(i)--)
#define fv(i,p) for(auto (i):(p))
#define ll long long
#define ull unsigned ll
#define pii pair<int,int>
#define pll pair<ll,ll>
#define _1st first
#define _2nd second
#define elif else if
#define debug cout<<endl<<"-------------------------------------------------------------"<<endl
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);cout.tie(NULL);
int T;
cin>>T;
while(T--){
ll Px,Py,Qx,Qy,Rx,Ry,Sx,Sy;
cin>>Px>>Py>>Qx>>Qy>>Rx>>Ry>>Sx>>Sy;
ll v1x=Qx-Px,v1y=Qy-Py;
ll v2x=Sx-Rx,v2y=Sy-Ry;
ll cross=v1x*v2y-v1y*v2x;
if(cross!=0){
cout<<"Yes\n";
}else{
ll lhs=(2*Rx-Px-Qx)*(2*Rx-Px-Qx)+(2*Ry-Py-Qy)*(2*Ry-Py-Qy);
ll rhs=(2*Sx-Px-Qx)*(2*Sx-Px-Qx)+(2*Sy-Py-Qy)*(2*Sy-Py-Qy);
if(lhs==rhs) cout<<"Yes\n";
else cout<<"No\n";
}
}
return 0;
}