模考集训DAY3
题解
T1(第k小):

这道题是一道 STL+模拟 的题,这道题一看就比较像搜索,但是dfs会超时,所以我们要考虑bfs。
一般的bfs是要用队列进行存储,但是这里我们需要找到第k小的数,所以我们需要一个能自动排序的容器,我们一下就能想到大根堆,但是我们也要处理重复的情况,那有没有既能去重又会排序的容器呢?撕……还真有,STL简直是全能战神啊,set既可以排序又会去重,简直是这道题的最佳人选,这样我们就可以用bfs进行搜索。
这样整体的思路就出来了,就是将 a 数组排序并去重,保证每一次bfs得到的结果都是剩下中最小的,然后进行bfs,但是这里bfs的结束条件从判断他是否为空变为他的长度有没有到达k这样就搞定了。
部分代码:
while(s1.size()<k){
ll x=*s.begin();
s.erase(x);
s1.insert(x);
for(ll i=1;i<=n;i++){
s.insert(x+a[i]);
}
}
T2(扑克欺诈):

这道题是一道典型的数学题+模拟,这道题需要用到概率论,小学奥数应该都学过的吧,所有可能数除目标可能数就是这件事在这个大事件里发生的概率。
当然,我不太懂这些东西,我只知道这次得到的结论就是:
先根据给定的数据求出最后的位置,然后倒着推概率,将概率相加,除以10即为所求
而因为其中已经到过的位置,到达最终位置的概率为1,其他的则有九种可能性,所以每一种位置i的概率是i*j(j取所有值)的概率的平均值。
所以可以得到部分代码:
for(ll i=idx;i>=1;i--){
// cout << p[i];
if(p[i]==0){
for(ll j=2;j<=11;j++){
ll t=(j==10?4:1);
p[i]+=t*p[i+j];
}
p[i]=p[i]/13;
}
if(i<=10){
ans+=p[i];
}
}
T3(候选人):
这是一道 二分答案 这道题很容易就能想到枚举 x,但是时间复杂度会超市,所以我们需要用二分优化
部分代码:
bool check(ll i, ll x){
ll pos=lower_bound(b+1, b+n+1, i+x+1)-b-1;
if(pos<n-m)return 0;
return (i+x+1)*(pos-n+m)-(sum[pos]-sum[n-m-1]-max(i, b[n-m]))>k-x;
}
T4(小信的积木):
这道题是一道纯暴力,dfs遍历整个棋盘,然后枚举每个棋盘的数字,只要枚举完一种棋盘就ans++,最后输出ans就可以了,非常简单,感觉不应该做为最后一题。
部分代码:
void dfs(ll x, ll y){
if(x>k+1){
ans++;
return;
}
if(y>a[x]){
dfs(x+1, 1);
return;
}
for(ll i=1;i<=n;i++){
if(i>g[x-1][y]&&i>=g[x][y-1]){
g[x][y]=i;
dfs(x,y+1);
}
}
}
做题情况
T1:这道题想了半天感觉像是搜索,调了很久样例过了,但是因为没算时间复杂度的原因只拿到了10分,其实正解也不咋么难,很可惜
TLE 10pt
T2:这道题算是比较难的,需要数学推理和概率论,感觉应该放在第四题,这道题我也用dfs搞了半天,但是样例美国,真的很惨。
WA 0pt
T3:这道题也很难,所以我没做。
WA 0pt
T4:这道题正解感觉好简单,但是后来没时间了,导致只能骗分,把 k=1 的情况用dfs写了出来,拿了20分
WA 20pt
总结
预期得分:120pt
实际得分:30pt
啊啊啊,这次实在是太失误了,还是内句话
\huge第一题不要想的太复杂,第二题不要想的太简单
ε=(´ο`*)))唉,祝我明天模考
\Huge AK!!!!