F,I,K,待补,L大模拟…
完整代码详细见,点击跳转
文章目录
The 2021 Shanghai Collegiate Programming Contest
A. 小 A 的点面论(暴力)
思路:直接枚举坐标判断是否符合即可
B. 小 A 的卡牌游戏(贪心优化dp)
思路:考虑如果是选择两种卡牌,即
A
+
B
=
n
A+B=n
A+B=n时,考虑用贪心,按照
b
i
−
a
i
b_i-a_i
bi−ai差越大排序,选择前
B
B
B项的
b
b
b,剩余选
a
a
a
那么对于三种卡牌
A
+
B
+
C
=
n
A+B+C=n
A+B+C=n,考虑
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]为前
i
i
i个里选
j
j
j个
c
c
c,那么对于不选
c
c
c时,我们还是考虑用两种卡牌时候的贪心做法选择
a
a
a和
b
b
b,这样就能把单纯暴力
d
p
dp
dp的
O
(
n
3
)
O(n^3)
O(n3)优化为
O
(
n
2
)
O(n^2)
O(n2)
C. 小 A 的期末考试(排序)
思路:按照题意模拟即可
D. Zztrans 的班级合照(dp)
思路:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示前
i
i
i个人里面有
j
j
j个人站在第二排
处理一下数组
a
[
i
]
a[i]
a[i],记录按升高排序后第
i
i
i名有
v
[
i
]
v[i]
v[i]个,那么对同一升高的人按同一批次进行处理,最后注意升高相同人不同要乘
v
[
i
]
!
v[i]!
v[i]!,对重复的部分枚举一下放置情况,总共
v
[
i
]
v[i]
v[i]个人,
k
k
k个人放第一排,
v
[
i
]
−
k
v[i]-k
v[i]−k个人放第二排
对于循环的每个阶段,第二排人数都是少于第一排的,因为放进来的人升高都是非降的
转移方程:
d
p
[
s
u
m
]
[
j
]
=
∑
d
p
[
s
u
m
−
v
[
i
]
]
[
j
−
k
]
dp[sum][j]=\sum dp[sum-v[i]][j-k]
dp[sum][j]=∑dp[sum−v[i]][j−k]
j
j
j是选中
s
u
m
sum
sum里后
j
j
j个数字,
k
k
k是枚举
0
0
0到
m
i
n
(
i
,
j
)
min(i,j)
min(i,j)
E. Zztrans 的庄园(期望)
思路:公式为: k ∗ ( ∑ p i ∗ m p [ c ] − 23 ) k*(\sum p_i*mp[c]-23) k∗(∑pi∗mp[c]−23),算一下即可
F. 鸡哥的限币令
G. 鸡哥的雕像(逆元)
思路:
a
n
s
=
∏
i
=
1
n
a
i
ans=\prod\limits_{i=1}^n a_i
ans=i=1∏nai,对于在第
i
i
i根能获得愉悦值为
a
n
s
∗
i
n
v
(
a
[
i
]
)
ans*inv(a[i])
ans∗inv(a[i])
但有一个错误点就是如果存在
a
[
i
]
=
m
o
d
a[i]=mod
a[i]=mod,那么显然对于非第
i
i
i根对应答案就是
0
0
0,如果存在两个或两个以上
a
[
i
]
=
m
o
d
a[i]=mod
a[i]=mod,那么所有答案均为
0
0
0
H. 鸡哥的 AI 驾驶(二分+思维)
思路:因为时间
t
t
t具有单调性,因此可以二分时间求解
我们考虑对于某个时间点,如果不同车型的车发生碰撞可以转化为不同车型的车的相对位置发生了变化
即我们考虑按照初始位置给所有车排序,那么对于某辆车的活动范围就被限制为它左右两侧最近那辆与它型号不同的车的位置,如果型号相同就可以继承前后那辆车的活动范围
for(int i=1;i<=n;i++){
if(a[i].t==a[i-1].t) l[i]=l[i-1];
else l[i]=i;
}
for(int i=n;i>=1;i--){
if(a[i].t==a[i+1].t)r[i]=r[i+1];
else r[i]=i;
}
那么我们再来考虑对于二分的某个时间点,我们对当时的位置排序,那么如果某辆车不在它应该在的活动范围就是
f
a
l
s
e
false
false
特殊的,要判断对于两车位置如果一样,他们的型号不一样的话就
f
a
l
s
e
false
false,对于型号只需要用他们初始活动范围是否相同即可判断
bool check(ll mid){
for(int i=1;i<=n;i++) pi[i]={a[i].p+a[i].v*mid,l[i]};
sort(pi+1,pi+1+n);
for(int i=1;i<=n;i++){
if(i!=1&&pi[i].first==pi[i-1].first&&pi[i].second!=pi[i-1].second) return false;
if(l[pi[i].second]>i||r[pi[i].second]<i) return false;
}
return true;
}
I. 对线
J. Alice and Bob-1(贪心)
思路:显然先把 a [ i ] a[i] a[i]降序排序,再考虑双方都想最优,那么显然 A l i c e Alice Alice每次选最大的, B o b Bob Bob选次大的,但有个注意点 A = ∣ ∑ j = 1 k a π j ∣ A=|\sum\limits_{j=1}^k a_{\pi j}| A=∣j=1∑kaπj∣,因此 A l i c e Alice Alice还有一种最优方法就是当 a i a_i ai存在很多负数时,从后往前选,因此选出这两种选法中较大的一种再用总和减去即可算出 B o b Bob Bob